LCOV - code coverage report
Current view: top level - src/67_common - m_epjdos.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 89.0 % 1102 981
Test Date: 2026-09-20 15:27:41 Functions: 85.7 % 14 12

            Line data    Source code
       1              : !!****m* ABINIT/m_epjdos
       2              : !! NAME
       3              : !!  m_epjdos
       4              : !!
       5              : !! FUNCTION
       6              : !!  Tools for the computiation of electronic PJDOSes
       7              : !!
       8              : !! COPYRIGHT
       9              : !!  Copyright (C) 2008-2026 ABINIT group (MVer, XG, SM, MT, BAmadon, MG, MB)
      10              : !!  This file is distributed under the terms of the
      11              : !!  GNU General Public License, see ~abinit/COPYING
      12              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      13              : !!
      14              : !! SOURCE
      15              : 
      16              : #if defined HAVE_CONFIG_H
      17              : #include "config.h"
      18              : #endif
      19              : 
      20              : #include "abi_common.h"
      21              : 
      22              : module m_epjdos
      23              : 
      24              :  use defs_basis
      25              :  use m_abicore
      26              :  use m_xmpi
      27              :  use m_errors
      28              :  use m_htetra
      29              :  use m_splines
      30              :  use m_cgtools
      31              :  use m_atomdata
      32              :  use m_crystal
      33              :  use m_ebands
      34              :  use m_nctk
      35              :  use netcdf
      36              :  use m_hdr
      37              :  use m_mpinfo
      38              :  use m_sort
      39              :  use m_dtset
      40              : 
      41              :  use defs_abitypes,    only : MPI_type
      42              :  use defs_datatypes,   only : pseudopotential_type
      43              :  use m_occ,            only : dos_hdr_write
      44              :  use m_time,           only : cwtime, timab
      45              :  use m_io_tools,       only : open_file
      46              :  use m_numeric_tools,  only : simpson, simpson_int
      47              :  use m_fstrings,       only : int2char4, strcat
      48              :  use m_special_funcs,  only : jlspline_t
      49              :  use m_kpts,           only : tetra_from_kptrlatt
      50              :  use m_kg,             only : ph1d3d, getph
      51              :  use m_gsphere,        only : getkpgnorm
      52              :  use m_fftcore,        only : sphereboundary
      53              :  use m_fft,            only : fftpac, fourwf, fourdp
      54              :  use m_pawrad,         only : pawrad_type, simp_gen
      55              :  use m_pawtab,         only : pawtab_type
      56              :  use m_pawcprj,        only : pawcprj_type, pawcprj_alloc, pawcprj_get, pawcprj_free
      57              :  use m_initylmg,       only : initylmg
      58              : 
      59              :  implicit none
      60              : 
      61              :  private
      62              : !!***
      63              : 
      64              :  public :: recip_ylm           ! Project input wavefunctions (real space) on to Ylm
      65              :  public :: dens_in_sph         ! Calculate integrated density in sphere around each atom
      66              : !!***
      67              : 
      68              : !----------------------------------------------------------------------
      69              : 
      70              : !!****t* m_epjdos/epjdos_t
      71              : !! NAME
      72              : !! epjdos_t
      73              : !!
      74              : !! FUNCTION
      75              : !!  Stores different contributions to the electronic DOS.
      76              : !!
      77              : !! NOTES
      78              : !!  Please contact gmatteo if you plan to change the internal implementation
      79              : !!  or add new DOSes. These results are saved in a netcdf file (see fatbands_ncwrite)
      80              : !!  so that one can read it with python and plot fatbands and PJDOSEs.
      81              : !!  The python version is able to handle the different cases (L, LM, Spin ...) but
      82              : !!  any change in the internal Abinit implementation is likely to break the python interface.
      83              : !!
      84              : !! SOURCE
      85              : 
      86              :  type,public :: epjdos_t
      87              : 
      88              :    integer :: mbesslang
      89              :    ! Max L+1 used in LM-DOS  (Bessel function expansion)
      90              : 
      91              :    integer :: ndosfraction
      92              :    ! Defines the last dimension of the dos arrays.
      93              :    ! Actual value depends on the other variables.
      94              : 
      95              :    integer :: prtdos
      96              :    ! 2 --> Standard DOS with tetra.
      97              :    ! 3 --> L-DOS with tetra (prtdosm>0 if LM is wanted in Ylm/Slm basis).
      98              :    ! 4 --> L-DOS with gaussian (prtdosm if LM is wanted in Ylm/Slm basis).
      99              :    ! 5 --> Spin-DOS
     100              : 
     101              :    integer :: prtdosm
     102              :    ! Option for the m-contributions to the partial DOS
     103              :    ! 1 if LM-projection is done onto complex Ylm
     104              :    ! 2 if LM-projection is done onto real Slm
     105              : 
     106              :    integer :: partial_dos_flag
     107              : 
     108              :    integer :: paw_dos_flag
     109              :    ! 1 if both PAW contributions are evaluated AND stored
     110              : 
     111              :    !integer :: pawfatbnd
     112              :    integer :: fatbands_flag
     113              : 
     114              :    integer :: nkpt, mband, nsppol
     115              :    ! Used to dimension arrays
     116              : 
     117              :    integer,allocatable :: mlang_type(:)
     118              :    ! mlang_type(ntypat + natsph_extra)
     119              :    ! Max L+1 used in LM-DOS for each atom type
     120              : 
     121              :    real(dp),allocatable :: fractions(:,:,:,:)
     122              :    ! fractions(nkpt,mband,nsppol,ndosfraction))
     123              :    ! TODO: replace nsppol with nspden = 1, 2 (nsppol==2) or 4 (nspinor==2)
     124              : 
     125              :    real(dp),allocatable :: fractions_m(:,:,:,:)
     126              :    ! fractions_m(nkpt,mband,nsppol,ndosfraction*mbesslang)
     127              : 
     128              :    real(dp),allocatable :: fractions_paw1(:,:,:,:)
     129              :    ! fractions_paw1(nkpt,mband,nsppol,ndosfraction)
     130              : 
     131              :    real(dp),allocatable :: fractions_pawt1(:,:,:,:)
     132              :    ! fractions_pawt1(nkpt,mband,nsppol,ndosfraction))
     133              : 
     134              :  contains
     135              : 
     136              :    procedure :: init => epjdos_init
     137              :      ! Create new object
     138              : 
     139              :    procedure :: calcnwrite => epjdos_calcnwrite
     140              :      ! Calculate DOS and write results to file(s).
     141              : 
     142              :    procedure :: partial_dos_fractions => partial_dos_fractions
     143              :      ! Calculate partial DOS fractions to feed to the tetrahedron method (PW part)
     144              : 
     145              :    procedure :: partial_dos_fractions_paw => partial_dos_fractions_paw
     146              :      ! Calculate PAW contributions to the partial DOS fractions.
     147              : 
     148              :    procedure :: prtfatbands => epjdos_prtfatbands
     149              :      ! Print PJDOS contributions in xmgrace format.
     150              : 
     151              :    procedure :: ncwrite => epjdos_ncwrite
     152              :      ! Write PJDOS contributions to netcdf file.
     153              : 
     154              :    procedure :: free => epjdos_free
     155              :    ! Free dynamic memory
     156              : 
     157              :  end type epjdos_t
     158              : 
     159              : !----------------------------------------------------------------------
     160              : 
     161              : contains  !============================================================
     162              : !!***
     163              : 
     164              : !!****f* m_epjdos/epjdos_init
     165              : !! NAME
     166              : !!  epjdos_init
     167              : !!
     168              : !! FUNCTION
     169              : !!  Create new object from dataset input variables.
     170              : !!
     171              : !! INPUTS
     172              : !!  dtset <type(dataset_type)>=all input variables for this dataset
     173              : !!  psps <type(pseudopotential_type)>=variables related to pseudopotentials
     174              : !!  pawtab(ntypat*usepaw) <type(pawtab_type)>=paw tabulated starting data
     175              : !!
     176              : !! SOURCE
     177              : 
     178           49 : subroutine epjdos_init(new, dtset, psps, pawtab)
     179              : 
     180              : !Arguments ------------------------------------
     181              :  class(epjdos_t),intent(inout) :: new
     182              :  type(dataset_type),intent(in) :: dtset
     183              :  type(pseudopotential_type),intent(in) :: psps
     184              :  type(pawtab_type),intent(in) :: pawtab(dtset%ntypat*psps%usepaw)
     185              : 
     186              : !Local variables-------------------------------
     187              : !scalars
     188              :  integer :: ierr,itypat,iat
     189              : ! *********************************************************************
     190              : 
     191              : !write(std_out,*)' m_epjdos%epjdos_new, enter '
     192              : 
     193           49 :  new%nkpt = dtset%nkpt; new%mband = dtset%mband; new%nsppol = dtset%nsppol
     194              : 
     195           49 :  new%prtdos = dtset%prtdos
     196           49 :  new%partial_dos_flag = 0
     197              :  if (new%prtdos==2) new%partial_dos_flag = 0 ! Standard DOS with tetra.
     198           49 :  if (new%prtdos==3) new%partial_dos_flag = 1 ! L-DOS with tetra (prtdosm>0 if LM is wanted in Ylm/Slm basis).
     199           49 :  if (new%prtdos==4) new%partial_dos_flag = 1 ! L-DOS with gaussian (prtdosm if LM is wanted in Ylm/Slm basis).
     200           49 :  if (new%prtdos==5) new%partial_dos_flag = 2 ! Spin DOS
     201              : 
     202           49 :  new%prtdosm=0
     203           49 :  if (new%partial_dos_flag==1) new%prtdosm=dtset%prtdosm
     204              :  ! paw_dos_flag= 1 if both PAW contributions are evaluated AND stored
     205           49 :  new%paw_dos_flag=0
     206           49 :  if (dtset%usepaw==1 .and. new%partial_dos_flag==1 .and. dtset%pawprtdos==1) new%paw_dos_flag=1
     207              : 
     208           49 :  new%fatbands_flag=0
     209           49 :  if (dtset%pawfatbnd>0 .and. new%prtdosm==0) new%fatbands_flag=1
     210           49 :  if (new%prtdosm==1.and.dtset%pawfatbnd>0)then
     211              : !  because they compute quantities in real and complex harmonics respectively
     212            0 :    ABI_ERROR('pawfatbnd>0  and prtdosm=1 are not compatible')
     213              :  end if
     214              : 
     215              :  ! mjv : initialization is needed as mbesslang is used for allocation below
     216              :  ! NOTE: 10/5/2010 the whole of this could be looped over ndosfraction,
     217              :  ! to store much less in memory. The DOS is accumulated in an array
     218              :  ! and then printed to file at the end.
     219           49 :  new%mbesslang = 1
     220           49 :  if (new%partial_dos_flag==1 .or. new%fatbands_flag==1) then
     221              : 
     222          132 :    ABI_MALLOC(new%mlang_type, (dtset%ntypat + dtset%natsph_extra))
     223          110 :    new%mlang_type = 0
     224              : 
     225              :    ! TODO: Could use mbesslang = 4 or compute it from psps/pawtab
     226              :    ! Increment by one (could underestimate if vloc = vlmax)
     227           44 :    if (dtset%usepaw == 0) then
     228           52 :      do iat=1,dtset%natsph
     229           32 :        itypat = dtset%typat(dtset%iatsph(iat))
     230          173 :        new%mlang_type(itypat) = 1 + maxval(psps%indlmn(1, :, itypat))
     231              :      end do
     232              :    else
     233           62 :      do iat=1,dtset%natsph
     234           38 :        itypat= dtset%typat(dtset%iatsph(iat))
     235           62 :        new%mlang_type(itypat) = 1 + (pawtab(itypat)%l_size - 1) / 2
     236              :      end do
     237              :    end if
     238              : 
     239              :    ! Up to l=g if we have natsph_extra.
     240           56 :    if (dtset%natsph_extra > 0) new%mlang_type(dtset%ntypat+1:) = 5
     241              : 
     242          110 :    new%mlang_type = 5  ! This is to preserve the old implementation
     243          110 :    new%mbesslang = maxval(new%mlang_type)
     244           44 :    new%ndosfraction = (dtset%natsph + dtset%natsph_extra) * new%mbesslang
     245              : 
     246            5 :  else if (new%partial_dos_flag == 2) then
     247            1 :    new%ndosfraction = 7
     248              : 
     249              :  else
     250            4 :    new%ndosfraction = 1
     251            4 :    new%mbesslang = 0
     252              :  end if
     253              : 
     254              :  ! Check allocations status as these arrays are not distributed and the wavefunctions are still in memory.
     255          294 :  ABI_MALLOC_OR_DIE(new%fractions, (dtset%nkpt,dtset%mband,dtset%nsppol,new%ndosfraction), ierr)
     256        66018 :  new%fractions = zero
     257              : 
     258           49 :  if (new%prtdosm>=1 .or. new%fatbands_flag==1) then
     259           18 :    ABI_MALLOC_OR_DIE(new%fractions_m,(dtset%nkpt,dtset%mband,dtset%nsppol,new%ndosfraction*new%mbesslang), ierr)
     260        57874 :    new%fractions_m = zero
     261              :  end if
     262              : 
     263           49 :  if (dtset%usepaw==1 .and. new%partial_dos_flag==1) then
     264          138 :    ABI_MALLOC_OR_DIE(new%fractions_paw1,(dtset%nkpt,dtset%mband,dtset%nsppol,new%ndosfraction), ierr)
     265          138 :    ABI_MALLOC_OR_DIE(new%fractions_pawt1,(dtset%nkpt,dtset%mband,dtset%nsppol,new%ndosfraction), ierr)
     266        66663 :    new%fractions_paw1 = zero; new%fractions_pawt1 = zero
     267              :  end if
     268              : 
     269              : !write(std_out,*)' m_epjdos%epjdos_new, exit '
     270              : 
     271           49 : end subroutine epjdos_init
     272              : !!***
     273              : 
     274              : !!****f* m_epjdos/epjdos_free
     275              : !! NAME
     276              : !!  epjdos_free
     277              : !!
     278              : !! FUNCTION
     279              : !!  Deallocate memory
     280              : !!
     281              : !! SOURCE
     282              : 
     283         1390 : subroutine epjdos_free(self)
     284              : 
     285              : !Arguments ------------------------------------
     286              :  class(epjdos_t),intent(inout) :: self
     287              : ! *********************************************************************
     288              : 
     289              :  ! integer
     290         1390 :  ABI_SFREE(self%mlang_type)
     291              : 
     292              :  ! real
     293         1390 :  ABI_SFREE(self%fractions)
     294         1390 :  ABI_SFREE(self%fractions_m)
     295         1390 :  ABI_SFREE(self%fractions_paw1)
     296         1390 :  ABI_SFREE(self%fractions_pawt1)
     297              : 
     298         1390 : end subroutine epjdos_free
     299              : !!***
     300              : 
     301              : !!****f* m_epjdos/epjdos_calcnwrite
     302              : !! NAME
     303              : !! epjdos_calcnwrite
     304              : !!
     305              : !! FUNCTION
     306              : !! calculate DOS and write results to file(s)
     307              : !!
     308              : !! INPUTS
     309              : !!  dos_fractions= projections of wavefunctions on each angular momentum Ylm
     310              : !!     which is the weight going into the DOS for an l-decomposed dos
     311              : !!  dos_fractions_m= same as dos_fractions, but m-decomposed not just l-
     312              : !!  dos_fractions_paw1= contribution to dos fractions from the PAW partial waves (phi)
     313              : !!  dos_fractions_pawt1= contribution to dos fractions from the PAW pseudo partial waves (phi_tild)
     314              : !!  dtset     structured datatype, in particular one uses :
     315              : !!   kptrlatt(3,3)=lattice vectors for full kpoint grid
     316              : !!   nshiftk      =number of kpoint grid shifts
     317              : !!   pawprtdos    =option to output the individual contributions to the partial DOS (0, 1 or 2)
     318              : !!   shiftk(3,nshiftk)=kpoint shifts
     319              : !!   usepaw       =option for PAW
     320              : !!  crystal<crystal_t>=Object defining the unit cell and its symmetries.
     321              : !!  ebands<ebands_t>=Band structure data.
     322              : !!  fermie=Fermi energy
     323              : !!  fildata=name of the DOS output file
     324              : !!  mbesslang=maximum angular momentum for Bessel function expansion
     325              : !!  prtdosm=option for the m-contributions to the partial DOS
     326              : !!  ndosfraction= number of types of DOS we are calculating, e.g. the number
     327              : !!    of l channels. Could be much more general, for other types of partial DOS
     328              : !!  paw_dos_flag= option for partial dos in PAW
     329              : !!  comm=MPI communicator.
     330              : !!
     331              : !! OUTPUT
     332              : !!  (no explicit output)
     333              : !!
     334              : !! SOURCE
     335              : 
     336           46 : subroutine epjdos_calcnwrite(dos,dtset,crystal,ebands,fildata,comm)
     337              : 
     338              : !Arguments ------------------------------------
     339              : !scalars
     340              :  class(epjdos_t),intent(in) :: dos
     341              :  integer,intent(in) :: comm
     342              :  character(len=*),intent(in) :: fildata
     343              :  type(dataset_type),intent(in) :: dtset
     344              :  type(crystal_t),intent(in) :: crystal
     345              :  type(ebands_t),intent(in) :: ebands
     346              : 
     347              : !Local variables-------------------------------
     348              : !scalars
     349              :  integer,parameter :: bcorr0=0,master=0
     350              :  integer :: iat,iband,iene,ikpt,isppol,natsph,natsph_extra,nkpt,nsppol,i1,i2
     351              :  integer :: nene,prtdos,unitdos,ierr,prtdosm,paw_dos_flag,mbesslang,ndosfraction
     352              :  integer :: my_rank,nprocs,cnt,ifrac,ii
     353              :  real(dp),parameter :: dos_max=9999.9999_dp
     354              :  real(dp) :: buffer,deltaene,enemax,enemin,integral_DOS,max_occ
     355              :  real(dp) :: cpu,wall,gflops
     356              :  logical :: bigDOS,iam_master
     357              :  character(len=10) :: tag
     358              :  character(len=500) :: frmt,frmt_extra,msg
     359           46 :  type(htetra_t) :: tetra
     360              : !arrays
     361           46 :  integer,allocatable :: unt_atsph(:)
     362              :  real(dp) :: list_dp(3)
     363           46 :  real(dp),allocatable :: tmp_eigen(:),total_dos(:,:,:),eig_dos(:,:)
     364           46 :  real(dp),allocatable :: dos_m(:,:,:),dos_paw1(:,:,:),dos_pawt1(:,:,:), wdt(:,:)
     365              : ! *********************************************************************
     366              : 
     367              : !write(std_out,*)' m_epjdos%dos_calcncwrite, enter '
     368              : 
     369           46 :  my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm); iam_master = (my_rank == master)
     370              : 
     371           46 :  prtdosm = dos%prtdosm; paw_dos_flag = dos%paw_dos_flag
     372           46 :  mbesslang = dos%mbesslang; ndosfraction = dos%ndosfraction
     373              : 
     374           46 :  nkpt = dtset%nkpt; nsppol = dtset%nsppol
     375              : 
     376              : !m-decomposed DOS not compatible with PAW-decomposed DOS
     377           46 :  if (prtdosm>=1.and.paw_dos_flag==1) then
     378            0 :    msg = 'm-decomposed DOS (prtdosm>=1) not compatible with PAW-decomposed DOS (pawprtdos=1) !'
     379            0 :    ABI_ERROR(msg)
     380              :  end if
     381              : 
     382              : !Refuse nband different for different kpoints
     383              : !Note: This means we can pass ebands%eig(:,:,:) instead of eigen(mband*nkpt*nsppol) in packed form
     384           98 :  do isppol=1,nsppol
     385          486 :    do ikpt=1,nkpt
     386          440 :      if ( dtset%nband(nkpt*(isppol-1) + ikpt) /= dtset%nband(1) ) then
     387            0 :        write(std_out,*) 'tetrahedron: skip subroutine.'
     388            0 :        write(std_out,*) 'nband must be the same for all kpoints'
     389            0 :        write(std_out,*) 'nband=', dtset%nband
     390            0 :        ABI_WARNING('tetrahedron: skip subroutine. See message above')
     391            0 :        return
     392              :      end if
     393              :    end do
     394              :  end do
     395              : 
     396           46 :  call cwtime(cpu, wall, gflops, "start")
     397              : 
     398              :  tetra = tetra_from_kptrlatt(crystal, dtset%kptopt, dtset%kptrlatt, dtset%nshiftk, &
     399           46 :    dtset%shiftk, dtset%nkpt, dtset%kpt, comm, msg, ierr)
     400           46 :  if (ierr /= 0) then
     401            0 :    call tetra%free()
     402            0 :    ABI_WARNING(msg)
     403            0 :    return
     404              :  end if
     405              : 
     406           46 :  natsph=dtset%natsph; natsph_extra=dtset%natsph_extra
     407              : 
     408              :  ! Master opens the DOS files.
     409           46 :  if (iam_master) then
     410           25 :    if (any(dtset%prtdos == [2, 5])) then
     411            5 :      if (open_file(fildata, msg, newunit=unitdos, status='unknown', form='formatted', action="write") /= 0) then
     412            0 :        ABI_ERROR(msg)
     413              :      end if
     414              : 
     415           20 :    else if (dtset%prtdos == 3) then
     416              :      ! unt_atsph(0) is used for the total DOS.
     417           60 :      ABI_MALLOC(unt_atsph,(0:natsph+natsph_extra))
     418              : 
     419              :      ! Open file for total DOS as well.
     420           20 :      if (open_file(strcat(fildata, '_TOTAL'), msg, newunit=unt_atsph(0), &
     421              :                    status='unknown', form='formatted', action="write") /= 0) then
     422           20 :        ABI_ERROR(msg)
     423              :      end if
     424              : 
     425           50 :      do iat=1,natsph
     426           30 :        call int2char4(dtset%iatsph(iat),tag)
     427           30 :        ABI_CHECK((tag(1:1)/='#'),'Bug: string length too short!')
     428           30 :        if (open_file(strcat(fildata, '_AT', tag), msg, newunit=unt_atsph(iat), &
     429           20 :                      status='unknown', form='formatted', action="write") /= 0) then
     430           30 :          ABI_ERROR(msg)
     431              :        end if
     432              :      end do
     433              :      ! do extra spheres in vacuum too. Use _ATEXTRA[NUM] suffix
     434           32 :      do iat=1,natsph_extra
     435           12 :        call int2char4(iat,tag)
     436           12 :        ABI_CHECK((tag(1:1)/='#'),'Bug: string length too short!')
     437           12 :        if (open_file(strcat(fildata, '_ATEXTRA', tag), msg, newunit=unt_atsph(natsph+iat), &
     438           20 :                      status='unknown', form='formatted', action="write") /= 0) then
     439           12 :          ABI_ERROR(msg)
     440              :        end if
     441              :      end do
     442              :    end if
     443              :  end if
     444              : 
     445              :  ! Write the header of the DOS file, and determine the energy range and spacing
     446           46 :  prtdos=dtset%prtdos
     447           46 :  buffer=0.01_dp ! Size of the buffer around the min and max ranges
     448              : 
     449              :  ! A Similar section is present is getnel. Should move all DOS stuff to m_ebands
     450              :  ! Choose the lower and upper energies
     451         6323 :  enemax = maxval(ebands%eig) + buffer
     452         6323 :  enemin = minval(ebands%eig) - buffer
     453              : 
     454              :  ! Extend the range to a nicer value
     455           46 :  enemax=0.1_dp*ceiling(enemax*10._dp)
     456           46 :  enemin=0.1_dp*floor(enemin*10._dp)
     457              : 
     458              :  ! Choose the energy increment
     459           46 :  if(abs(dtset%dosdeltae)<tol10)then
     460           44 :    deltaene=0.001_dp
     461           44 :    if(dtset%prtdos>=2)deltaene=0.0005_dp ! Higher resolution possible (and wanted) for tetrahedron
     462              :  else
     463            2 :    deltaene=dtset%dosdeltae
     464              :  end if
     465           46 :  nene=nint((enemax-enemin)/deltaene)+1
     466              : 
     467           46 :  call xmpi_bcast(nene, master, comm, ierr)
     468          121 :  if (iam_master) list_dp(1:3) = [deltaene, enemin, enemax]
     469           46 :  call xmpi_bcast(list_dp, master, comm, ierr)
     470           46 :  deltaene = list_dp(1); enemin = list_dp(2); enemax = list_dp(3)
     471              : 
     472           46 :  if (iam_master) then
     473           25 :    if (any(dtset%prtdos == [2, 5])) then
     474              :      call dos_hdr_write(deltaene,ebands%eig,enemax,enemin,ebands%fermie,ebands%fermih,&
     475              :      dtset%mband,dtset%nband,nene,nkpt,nsppol,dtset%occopt,prtdos,&
     476            5 :      dtset%tphysel,dtset%tsmear,unitdos)
     477           20 :    else if (dtset%prtdos == 3) then
     478           82 :      do iat=0,natsph+natsph_extra
     479              :        call dos_hdr_write(deltaene,ebands%eig,enemax,enemin,ebands%fermie,ebands%fermih,&
     480              :        dtset%mband,dtset%nband,nene,nkpt,nsppol,dtset%occopt,prtdos,&
     481           82 :        dtset%tphysel,dtset%tsmear,unt_atsph(iat))
     482              :      end do
     483              :    end if
     484              :  end if
     485              : 
     486              :  ! Tetra weights
     487          138 :  ABI_MALLOC(wdt, (nene, 2))
     488              : 
     489              :  ! Allocate arrays to store DOSes and fill with zeros.
     490              :  ! 1--> DOS , 2--> IDOS
     491          230 :  ABI_MALLOC(total_dos,(nene,ndosfraction,2))
     492           92 :  ABI_MALLOC(eig_dos, (nene, 2))
     493              : 
     494           46 :  if (paw_dos_flag==1) then
     495            0 :    ABI_MALLOC(dos_paw1,(nene,ndosfraction,2))
     496            0 :    ABI_MALLOC(dos_pawt1,(nene,ndosfraction,2))
     497              :  end if
     498           46 :  if (prtdosm>=1) then
     499           10 :    ABI_MALLOC(dos_m, (nene,ndosfraction*mbesslang,2))
     500              :  end if
     501              : 
     502              : !Get maximum occupation value (2 or 1)
     503           46 :  max_occ = one; if (dtset%nspinor == 1 .and. nsppol == 1) max_occ = two
     504              : 
     505              : !-------------------------------------------------------------------
     506              : !For each spin polarisation and band, interpolate band over kpoints
     507              : !calculate integration weights and DOS contib from
     508              : !-------------------------------------------------------------------
     509              : 
     510              :  ! Workspace arrays.
     511          138 :  ABI_MALLOC(tmp_eigen,(nkpt))
     512              : 
     513           46 :  cnt = 0
     514           98 :  do isppol=1,nsppol
     515              : 
     516      7702572 :    total_dos = zero; eig_dos = zero
     517       900458 :    if (prtdosm>=1) dos_m = zero
     518           52 :    if (paw_dos_flag==1) then
     519            0 :      dos_paw1 = zero; dos_pawt1 = zero
     520              :    end if
     521              : 
     522          440 :    do ikpt=1,nkpt
     523         6277 :       do iband=1,ebands%nband(ikpt+(isppol-1)*ebands%nkpt)
     524         5837 :         cnt = cnt + 1; if (mod(cnt, nprocs) /= my_rank) cycle ! Mpi parallelism.
     525              : 
     526              :         ! Accumulate total DOS from eigenvalues (this is the **exact** total DOS)
     527        24672 :         tmp_eigen(:) = ebands%eig(iband, :, isppol)
     528         2837 :         call tetra%get_onewk(ikpt,bcorr0,nene,nkpt,tmp_eigen,enemin,enemax,max_occ,wdt)
     529     48586585 :         wdt = wdt*ebands%wtk(ikpt)
     530     48589422 :         eig_dos = eig_dos + wdt
     531              : 
     532              :         ! Accumulate L-DOS.
     533         8511 :         do ii=1,2
     534        46713 :           do ifrac=1,ndosfraction
     535    383816878 :             total_dos(:,ifrac,ii) = total_dos(:,ifrac,ii) + wdt(:,ii) * dos%fractions(ikpt,iband,isppol,ifrac)
     536              :           end do
     537              :         end do
     538              : 
     539         2837 :         if (paw_dos_flag==1) then
     540              :           ! Accumulate L-DOS (on-site terms).
     541            0 :           do ii=1,2
     542            0 :             do ifrac=1,ndosfraction
     543            0 :               dos_paw1(:,ifrac,ii) = dos_paw1(:,ifrac,ii) + wdt(:,ii) * dos%fractions_paw1(ikpt,iband,isppol,ifrac)
     544            0 :               dos_pawt1(:,ifrac,ii) = dos_pawt1(:,ifrac,ii) + wdt(:,ii) * dos%fractions_pawt1(ikpt,iband,isppol,ifrac)
     545              :             end do
     546              :           end do
     547              :         end if
     548              : 
     549         3225 :         if (prtdosm>=1) then
     550              :          ! Accumulate LM-DOS.
     551          609 :          do ii=1,2
     552        10909 :            do ifrac=1,ndosfraction*mbesslang
     553     86141006 :              dos_m(:,ifrac,ii) = dos_m(:,ifrac,ii) + wdt(:,ii) * dos%fractions_m(ikpt, iband, isppol, ifrac)
     554              :            end do
     555              :          end do
     556              :         end if
     557              : 
     558              :       end do ! ikpt
     559              :    end do ! iband
     560              : 
     561              :    ! Collect results on master
     562           52 :    call xmpi_sum_master(eig_dos, master, comm, ierr)
     563           52 :    call xmpi_sum_master(total_dos, master, comm, ierr)
     564      3446676 :    bigDOS=(maxval(total_dos(:,:,1))>999._dp)
     565              : 
     566           52 :    if (paw_dos_flag == 1) then
     567            0 :      call xmpi_sum_master(dos_paw1, master, comm, ierr)
     568            0 :      call xmpi_sum_master(dos_pawt1, master, comm, ierr)
     569              :    end if
     570           52 :    if (prtdosm >= 1) call xmpi_sum_master(dos_m, master, comm, ierr)
     571              : 
     572              :    ! Write the DOS value in the DOS file
     573              :    ! Print the data for this energy. Note the upper limit (dos_max), to be consistent with the format.
     574              :    ! The use of "E" format is not adequate, for portability of the self-testing procedure.
     575              :    ! header lines depend on the type of DOS (projected etc...) which is output
     576              : 
     577           52 :    if (.not. iam_master) goto 10
     578           31 :    call write_extra_headers()
     579              : 
     580           31 :    if (prtdos==2) then
     581              :      ! E, DOS, IDOS
     582        23610 :      do iene=1,nene
     583              :        write(unitdos, '(f11.5,1x,2(f10.4,1x))') &
     584        47215 :         enemin + (iene-1)*deltaene, min(total_dos(iene,:,1), dos_max), total_dos(iene,:,2)
     585              :      end do
     586              : 
     587           26 :    else if (prtdos==3) then
     588              : 
     589              :      ! Write E, DOS, IDOS
     590       142330 :      do iene=1,nene
     591              :        write(unt_atsph(0), '(f11.5,1x,2(f10.4,1x))') &
     592       142330 :         enemin + (iene-1)*deltaene, min(eig_dos(iene,1), dos_max), eig_dos(iene,2)
     593              :      end do
     594              : 
     595              :      ! E, DOS(L=1,LMAX), IDOS(L=1,LMAX)
     596              :      ! Here we assume mpsang = 5 in the format.
     597           25 :      if (paw_dos_flag/=1.or.dtset%pawprtdos==2) then
     598           25 :        frmt = '(f11.5,1x,5(f9.4,1x),10x,5(f8.2,1x),10x,25(f8.2,1x))'
     599           25 :        if (bigDOS) frmt = '(f11.5,1x,5(f10.4,1x),10x,5(f8.2,1x),10x,25(f8.2,1x))'
     600              :        ! for extra atoms in vacuum need more precision
     601           25 :        frmt_extra = '(f11.5,1x,5(f20.16,1x),10x,5(f20.16,1x),10x,25(f20.16,1x))'
     602              : 
     603           60 :        do iat=1,natsph
     604           35 :          i1 = (iat-1)*mbesslang+1; i2 = iat*mbesslang
     605           60 :          if (prtdosm==0) then
     606       216542 :            do iene=1,nene
     607       216511 :              write(unt_atsph(iat), fmt=frmt) enemin + (iene-1)*deltaene, &
     608      1515608 :                min(total_dos(iene, i1:i2, 1), dos_max), total_dos(iene, i1:i2,2)
     609              :            end do
     610              :          else
     611        18008 :            do iene=1,nene
     612        18004 :              write(unt_atsph(iat), fmt=frmt) enemin + (iene-1)*deltaene, &
     613       108024 :                min(total_dos(iene, i1:i2, 1), dos_max),&
     614        18004 :                total_dos(iene, i1:i2, 2),&
     615       486112 :                min(dos_m(iene,(iat-1)*mbesslang**2+1:iat*mbesslang**2,1), dos_max)
     616              :            end do
     617              :          end if
     618              :        end do
     619              : 
     620              :        ! Extra spheres.
     621           37 :        do iat=natsph+1,natsph+natsph_extra
     622           12 :          i1 = (iat-1)*mbesslang+1; i2 = iat*mbesslang
     623           37 :          if (prtdosm==0) then
     624        14424 :            do iene=1,nene
     625        14412 :              write(unt_atsph(iat), fmt=frmt_extra) enemin + (iene-1)*deltaene, &
     626        14412 :               total_dos(iene, i1:i2, 1), &
     627        28836 :               total_dos(iene, i1:i2, 2)
     628              :            end do
     629              :          else
     630            0 :            do iene=1,nene
     631            0 :              write(unt_atsph(iat), fmt=frmt_extra) enemin + (iene-1)*deltaene, &
     632            0 :               total_dos(iene, i1:i2, 1),&
     633            0 :               total_dos(iene, i1:i2, 2),&
     634            0 :               dos_m(iene,(iat-1)*mbesslang**2+1:iat*mbesslang**2, 1)
     635              :            end do
     636              :          end if
     637              :        end do
     638              : 
     639              :      else
     640            0 :        frmt = '(f11.5,1x,5(f9.4,1x),3(6x,5f9.4))'
     641            0 :        if (bigDOS) frmt = '(f11.5,1x,5(f10.4,1x),3(6x,5f10.4))'
     642              :        ! for extra atom spheres in vacuum need more precision
     643            0 :        frmt_extra = '(f11.5,1x,5(f20.16,1x),3(6x,5f20.16))'
     644              : 
     645            0 :        do iat=1,natsph
     646            0 :          i1 = iat*5-4; i2 = iat*5
     647            0 :          do iene=1,nene
     648            0 :            write(unt_atsph(iat), fmt=frmt) enemin + (iene-1)*deltaene, &
     649            0 :             min(total_dos(iene,i1:i2,1), dos_max),&
     650            0 :             min(total_dos(iene,i1:i2,1) - dos_paw1(iene,i1:i2,1) + dos_pawt1(iene,i1:i2,1), dos_max),&
     651            0 :             min(dos_paw1(iene,i1:i2,1), dos_max),&
     652            0 :             min(dos_pawt1(iene,i1:i2,1), dos_max)
     653              :          end do
     654              :        end do
     655              : 
     656              :        ! Extra spheres.
     657            0 :        do iat=natsph+1,natsph+natsph_extra
     658            0 :          i1 = iat*5-4; i2 = iat*5
     659            0 :          do iene=1,nene
     660            0 :            write(unt_atsph(iat), fmt=frmt_extra) enemin + (iene-1)*deltaene, &
     661            0 :              min(total_dos(iene,i1:i2,1), dos_max),&
     662            0 :              min(total_dos(iene,i1:i2,1) - dos_paw1(iene,i1:i2,1) + dos_pawt1(iene,i1:i2,1), dos_max),&
     663            0 :              min(dos_paw1(iene,i1:i2,1), dos_max),&
     664            0 :              min(dos_pawt1(iene,i1:i2,1), dos_max)
     665              :          end do
     666              :        end do
     667              :      end if
     668              : 
     669            1 :    else if (prtdos==5)then
     670              :      ! E, SPIN-DOS
     671            1 :      frmt = '(f11.5,1x,7(f9.4,1x),10x,7(f8.2,1x))'
     672            1 :      if (bigDOS) frmt = '(f11.5,1x,7(f10.4,1x),10x,7(f8.2,1x))'
     673         9402 :      do iene=1,nene
     674        75209 :        write(unitdos, fmt=frmt) enemin + (iene-1)*deltaene, min(total_dos(iene,1:7,1), dos_max), total_dos(iene,1:7,2)
     675              :      end do
     676              :    end if
     677              : 
     678              : 10 continue
     679          464 :    integral_DOS=sum(total_dos(nene,:,2))
     680           52 :    write(msg, '(a,es16.8)' ) ' tetrahedron : integrate to',integral_DOS
     681           98 :    call wrtout(std_out,msg)
     682              :  end do ! isppol
     683              : 
     684              :  ! Close files.
     685           46 :  if (iam_master) then
     686           25 :    if (any(prtdos == [2, 5])) then
     687            5 :      close(unitdos)
     688           20 :    else if (prtdos == 3) then
     689           82 :      do iat=0,natsph+natsph_extra
     690           82 :        close(unt_atsph(iat))
     691              :      end do
     692           20 :      ABI_FREE(unt_atsph)
     693              :    end if
     694              :  end if
     695              : 
     696           46 :  ABI_FREE(tmp_eigen)
     697           46 :  ABI_FREE(total_dos)
     698           46 :  ABI_FREE(wdt)
     699           46 :  ABI_FREE(eig_dos)
     700              : 
     701           46 :  if (prtdosm>=1)  then
     702            2 :    ABI_FREE(dos_m)
     703              :  end if
     704              : 
     705           46 :  if (paw_dos_flag==1)  then
     706            0 :    ABI_FREE(dos_paw1)
     707            0 :    ABI_FREE(dos_pawt1)
     708              :  end if
     709              : 
     710           46 :  call tetra%free()
     711              : 
     712           46 :  call cwtime(cpu,wall,gflops,"stop")
     713           46 :  write(msg,'(2(a,f8.2),a)')" tetrahedron: cpu_time: ",cpu,"[s], walltime: ",wall," [s]"
     714          138 :  call wrtout(std_out,msg,"PERS")
     715              : 
     716              :  !write(std_out,*)' m_epjdos%dos_calcncwrite, exit '
     717              : 
     718              : contains
     719              : 
     720           31 : subroutine write_extra_headers()
     721              : 
     722           31 :  if (nsppol==2) then
     723           12 :    if(isppol==1) write(msg,'(a,16x,a)')  '#','Spin-up DOS'
     724           12 :    if(isppol==2) write(msg,'(2a,16x,a)')  ch10,'#','Spin-dn DOS'
     725              :    ! NB: dtset%prtdos == 5 should not happen for nsppol==2
     726              : 
     727           12 :    if (any(dtset%prtdos == [2, 5])) then
     728            2 :      write(unitdos, "(a)")trim(msg)
     729              : 
     730           10 :    else if (dtset%prtdos == 3) then
     731           30 :      do iat=0,natsph+natsph_extra
     732           30 :        write(unt_atsph(iat), "(a)")trim(msg)
     733              :      end do
     734              :    end if
     735              : 
     736              :  end if
     737              : 
     738           31 :  if (prtdos==2) then
     739            5 :    write(unitdos, '(a)' )'# energy(Ha)     DOS  integrated DOS'
     740              : 
     741           26 :  else if (prtdos==3) then
     742              : 
     743           25 :    write(unt_atsph(0), '(a)' )'# energy(Ha)     DOS  integrated DOS'
     744              : 
     745           25 :    if (paw_dos_flag/=1.or.dtset%pawprtdos==2) then
     746           60 :      do iat=1,natsph
     747              :        write(unt_atsph(iat), '(3a,i5,a,i5,a,a,es16.6,3a)' ) &
     748           35 :         '# Local DOS (columns 2-6) and integrated local DOS (columns 7-11),',ch10,&
     749           35 :         '# for atom number iat=',iat,'  iatom=',dtset%iatsph(iat),ch10,&
     750           70 :         '# inside sphere of radius ratsph=',dtset%ratsph(dtset%typat(dtset%iatsph(iat))),' Bohr.',ch10,"#"
     751              : 
     752           35 :        if (dtset%usepaw==1.and.dtset%pawprtdos==2) then
     753              :          write(unt_atsph(iat), '(3a)' ) &
     754            6 :           '# PAW: note that only all-electron on-site part has been used to compute DOS !',ch10,"#"
     755              :        end if
     756           35 :        if (bigDOS) then
     757              :          write(msg, '(a,a)' ) &
     758           14 :           '# energy(Ha)   l=0       l=1       l=2       l=3       l=4',&
     759           28 :           '    (integral=>)  l=0     l=1     l=2     l=3     l=4'
     760              :        else
     761              :          write(msg, '(a,a)' ) &
     762           21 :           '# energy(Ha)  l=0      l=1      l=2      l=3      l=4',&
     763           42 :           '    (integral=>)  l=0     l=1     l=2     l=3     l=4'
     764              :        end if
     765           35 :        if (prtdosm>=1) then
     766            4 :          write(msg, '(7a)' ) trim(msg),'          ',&
     767            4 :           '  lm=0 0',&
     768            4 :           '  lm=1-1  lm=1 0  lm=1 1',&
     769            4 :           '  lm=2-2  lm=2-1  lm=2 0  lm=2 1  lm=2 2',&
     770            4 :           '  lm=3-3  lm=3-2  lm=3-1  lm=3 0  lm=3 1  lm=3 2  lm=3 3',&
     771            8 :           '  lm=4-4  lm=4-3  lm=4-2  lm=4-1  lm=4 0  lm=4 1  lm=4 2  lm=4 3  lm=4 4'
     772              :        end if
     773           60 :        write(unt_atsph(iat), "(a)")trim(msg)
     774              :      end do
     775              :    else
     776            0 :      do iat=1,natsph
     777              :        write(unt_atsph(iat), '(9a,i5,a,i5,a,a,es16.6,3a)' ) &
     778            0 :         '# Local DOS (columns 2-6),',ch10,&
     779            0 :         '#  plane-waves contrib. to DOS (columns 7-11),',ch10,&
     780            0 :         '#  AE on-site  contrib. to DOS (columns 12-16),',ch10,&
     781            0 :         '# -PS on-site  contrib. to DOS (columns 17-21),',ch10,&
     782            0 :         '# for atom number iat=',iat,'  iatom=',dtset%iatsph(iat),ch10,&
     783            0 :         '# inside sphere of radius ratsph=',dtset%ratsph(dtset%typat(dtset%iatsph(iat))),' Bohr.',ch10,"#"
     784            0 :        if (bigDOS) then
     785              :          write(msg, '(4a)' ) &
     786            0 :           '#energy(Ha)   l=0       l=1       l=2       l=3       l=4',&
     787            0 :           '       (PW)  l=0       l=1       l=2       l=3       l=4',&
     788            0 :           '      (Phi)  l=0       l=1       l=2       l=3       l=4',&
     789            0 :           '     (tPhi)  l=0       l=1       l=2       l=3       l=4'
     790              :        else
     791              :          write(msg, '(4a)' ) &
     792            0 :           '#energy(Ha)  l=0      l=1      l=2      l=3      l=4',&
     793            0 :           '       (PW) l=0      l=1      l=2      l=3      l=4',&
     794            0 :           '      (Phi) l=0      l=1      l=2      l=3      l=4',&
     795            0 :           '     (tPhi) l=0      l=1      l=2      l=3      l=4'
     796              :        end if
     797            0 :        write(unt_atsph(iat), "(a)")trim(msg)
     798              :      end do
     799              :    end if
     800           37 :    do iat=1,natsph_extra
     801              :      write(unt_atsph(natsph+iat), '(3a,i5,2a,es16.6,3a)' ) &
     802           12 :       '# Local DOS (columns 2-6) and integrated local DOS (columns 7-11),',ch10,&
     803           12 :       '# for non-atomic sphere number iat=',iat,ch10,&
     804           24 :       '# of radius ratsph=',dtset%ratsph_extra,' Bohr.',ch10,"#"
     805           12 :      if (bigDOS) then
     806              :        write(msg, '(a,a)' ) &
     807            0 :         '# energy(Ha)   l=0       l=1       l=2       l=3       l=4',&
     808            0 :         '    (integral=>)  l=0     l=1     l=2     l=3     l=4'
     809              :      else
     810              :        write(msg, '(a,a)' ) &
     811           12 :         '# energy(Ha)  l=0      l=1      l=2      l=3      l=4',&
     812           24 :         '    (integral=>)  l=0     l=1     l=2     l=3     l=4'
     813              :      end if
     814           12 :      if (prtdosm>=1) then
     815            0 :        write(msg, '(7a)' ) trim(msg),'          ',&
     816            0 :         '  lm=0 0',&
     817            0 :         '  lm=1-1  lm=1 0  lm=1 1',&
     818            0 :         '  lm=2-2  lm=2-1  lm=2 0  lm=2 1  lm=2 2',&
     819            0 :         '  lm=3-3  lm=3-2  lm=3-1  lm=3 0  lm=3 1  lm=3 2  lm=3 3',&
     820            0 :         '  lm=4-4  lm=4-3  lm=4-2  lm=4-1  lm=4 0  lm=4 1  lm=4 2  lm=4 3  lm=4 4'
     821              :      end if
     822           37 :      write(unt_atsph(natsph+iat), "(a)")trim(msg)
     823              :    end do
     824              : 
     825            1 :  else if (prtdos==5) then
     826              :    write(unitdos, '(a)' )&
     827            1 :      '# energy(Ha)     DOS up,up  up,dn  dn,up  dn,dn  sigma_x sigma_y sigma_z  and integrated DOS components'
     828              :  end if ! prtdos value
     829              : 
     830           31 : end subroutine write_extra_headers
     831              : 
     832              : end subroutine epjdos_calcnwrite
     833              : !!***
     834              : 
     835              : !!****f* m_epjdos/recip_ylm
     836              : !! NAME
     837              : !! recip_ylm
     838              : !!
     839              : !! FUNCTION
     840              : !! Project input wavefunctions in reciprocal space on to Ylm
     841              : !! (real or complex harmonics depending on rc_ylm).
     842              : !!
     843              : !! INPUTS
     844              : !!  bess_fit(mpw,nradintmax,ll) = Bessel functions for L, splined
     845              : !!   with arguments $2 \pi |k+G| \Delta r$, for all G vectors in sphere
     846              : !!   and all points on radial grid.
     847              : !!  cg_1band(2,npw_k)=wavefunction in recip space (note that nspinor is missing, see Notes).
     848              : !!  istwfk= storage mode of cg_1band
     849              : !!  nradint(natsph)=number of points on radial real-space grid for a given atom.
     850              : !!  nradintmax=dimension of rint array.
     851              : !!  me_g0=1 if this processor has G=0, 0 otherwise
     852              : !!  mlang=maximum angular momentum in Bessel functions.
     853              : !!  mpw=Maximum number of planewaves. Used to dimension bess_fit
     854              : !!  natsph=number of atoms around which ang mom projection has to be done
     855              : !!  typat_extra(natsph)=Type of each atom. ntypat + 1 if empty sphere
     856              : !!  mlang_type(ntypat + natsph_extra)=Max L+1 for each atom type
     857              : !!  npw_k=number of plane waves for this kpt
     858              : !!  nspinor=number of spinor components
     859              : !!  ph3d(2,npw_k,natsph)=3-dim structure factors, for each atom and plane wave.
     860              : !!  prtsphere= if 1, print a complete analysis of the angular momenta in atomic spheres
     861              : !!  rint(nradintmax) = points on radial real-space grid for integration
     862              : !!  rmax(natsph)=maximum radius for real space integration sphere
     863              : !!  rc_ylm= 1 for real spherical harmonics. 2 for complex spherical harmonics,
     864              : !!  ucvol=unit cell volume in bohr**3.
     865              : !!  ylm_k(npw_k,mlang**2)=real spherical harmonics for each G and LM.
     866              : !!  znucl_sph(natsph)=gives the nuclear number for each type of atom
     867              : !!
     868              : !! OUTPUT
     869              : !!  sum_1ll_1atom(mlang,natsph)= projected scalars for each atom and ang. mom.
     870              : !!  sum_1lm_1atom(mlang*mlang,natsph)= projected scalars for each atom and LM component.
     871              : !!  cplx_1lm_1atom(2,dtset%nspinor**2,dos%mbesslang**2,natsph_tot) = complex projection of wave function on atomic like orbital
     872              : !!
     873              : !! NOTES
     874              : !!  * ph3d atoms are ordered with natsph and must be provided by the caller in the correct order!
     875              : !!
     876              : !!  * spinor components are not treated here. This facilitates the implementation of spinor parallelism
     877              : !!    because the caller can easily call the routine inside a loop over spinors and then sum the
     878              : !!    different contributions outside the loop thus reducing the number of MPI calls.
     879              : !!
     880              : !! SOURCE
     881              : 
     882        12852 : subroutine recip_ylm (bess_fit, cg_1band, istwfk, mpi_enreg, nradint, nradintmax, mlang,&
     883         4284 : &  mpw, natsph, typat_extra, mlang_type, npw_k, nspinor, ph3d, prtsphere, rint, rmax,&
     884         4284 : &  rc_ylm, sum_1ll_1atom, sum_1lm_1atom, cplx_1lm_1atom, ucvol, ylm_k, znucl_sph)
     885              : 
     886              : !Arguments ------------------------------------
     887              : !scalars
     888              :  integer,intent(in) :: istwfk,mlang,mpw,natsph,npw_k,nradintmax
     889              :  integer,intent(in) :: nspinor
     890              :  integer,intent(in) :: prtsphere,rc_ylm
     891              :  real(dp),intent(in) :: ucvol
     892              : !arrays
     893              :  integer,intent(in) :: nradint(natsph),typat_extra(natsph),mlang_type(:)
     894              :  real(dp),intent(in) :: bess_fit(mpw,nradintmax,mlang),cg_1band(:,:) !(2,my_nspinor*npw_k)
     895              :  real(dp),intent(in) :: ph3d(2,npw_k,natsph),rint(nradintmax)
     896              :  real(dp),intent(in) :: rmax(natsph),ylm_k(npw_k,mlang*mlang)
     897              :  real(dp),intent(in) :: znucl_sph(natsph)
     898              :  type(MPI_type),intent(in) :: mpi_enreg
     899              :  real(dp),intent(out) :: sum_1ll_1atom(nspinor**2, mlang, natsph)
     900              :  real(dp),intent(out) :: sum_1lm_1atom(nspinor**2, mlang*mlang,natsph)
     901              :  real(dp),intent(out) :: cplx_1lm_1atom(2,nspinor, mlang*mlang,natsph)
     902              : 
     903              : !Local variables-------------------------------
     904              : !scalars
     905              :  integer :: ilm,iat,ipw,ixint,ll,mm,il,jlm,ierr,lm_size,itypat, ispinor,ipauli, is, isp, my_nspinor
     906              :  real(dp),parameter :: invsqrt2=one/sqrt2
     907              :  real(dp) :: sum_all, dr, fact
     908              :  type(atomdata_t) :: atom
     909              :  character(len=500) :: msg
     910              : !arrays
     911         8568 :  integer :: ilang(mlang**2)
     912         4284 :  integer, allocatable :: ispinors(:)
     913         8568 :  real(dp) :: c1(2),c2(2), sum_1atom(natsph),sum_1ll(mlang),sum_1lm(mlang**2)
     914         8568 :  real(dp) :: func(nradintmax), func_cplx(nradintmax,2)
     915         8568 :  complex(dp) :: vect(npw_k)
     916         4284 :  complex(dp),allocatable :: tmppsia(:,:),tmppsim(:,:),dotc(:), values(:,:,:,:)
     917              : ! *************************************************************************
     918              : 
     919              :  ! Workspace array (used to reduce the number of MPI communications)
     920              :  ! One could reduce a bit the memory requirement by using non-blocking operations ...
     921        25704 :  ABI_MALLOC_OR_DIE(values, (nradintmax, nspinor, mlang**2, natsph), ierr)
     922     81628070 :  values = czero
     923              : 
     924         4284 :  my_nspinor = max(1,nspinor/mpi_enreg%nproc_spinor)
     925        17136 :  ABI_MALLOC(tmppsia, (npw_k,my_nspinor))
     926        12852 :  ABI_MALLOC(tmppsim, (npw_k,my_nspinor))
     927        12852 :  ABI_MALLOC(dotc, (my_nspinor))
     928        12852 :  ABI_MALLOC(ispinors, (my_nspinor))
     929         4284 :  if (my_nspinor == 2) then
     930          496 :    ispinors(1) = 1
     931          496 :    ispinors(2) = 2
     932              :  else
     933         3788 :    ispinors(1) = mpi_enreg%me_spinor+1
     934              :  end if
     935              : 
     936       519720 :  sum_1lm_1atom = zero
     937       841520 :  cplx_1lm_1atom = zero
     938              : 
     939        25704 :  do ll=0,mlang-1
     940       132804 :    do mm=-ll,ll
     941       107100 :      ilm = (ll+1)**2-ll+mm
     942       128520 :      ilang(ilm) = ll+1
     943              :    end do
     944              :  end do
     945              : 
     946              :  ! Big loop on all atoms
     947        10720 :  do iat=1,natsph
     948         6436 :    itypat = typat_extra(iat)
     949         6436 :    lm_size = mlang_type(itypat) ** 2
     950         6436 :    dr = rmax(iat) / (nradint(iat)-1)
     951              : 
     952              :    ! u(G) e^{i(k+G).Ra}
     953              :    ! tmppsia = Temporary array for part which depends only on iat
     954        13768 :    do ispinor=1,my_nspinor
     955      1293880 :      do ipw=1,npw_k
     956              :        tmppsia(ipw,ispinor) = dcmplx(cg_1band(1,ipw+(ispinor-1)*npw_k),cg_1band(2,ipw+(ispinor-1)*npw_k)) &
     957      1287444 : &            * dcmplx(ph3d(1,ipw,iat), ph3d(2,ipw,iat))
     958              :      end do
     959              :    end do
     960              : 
     961              :    ! tmppsim = temporary arrays for part of psi which does not depend on ixint = tmppsia * ylm.
     962              :    ! could remove this intermediate array to save memory...
     963              :    ! u(G) Y_LM^*(k+G) e^{i(k+G).Ra}
     964              :    ! Take into account the fact that ylm_k are REAL spherical harmonics, see initylmg.f
     965              :    ! For time-reversal states, detailed treatment show that only the real or imaginary
     966              :    ! part of tmppsia is needed here, depending on l being even or odd: only one of the coef is 1, the other 0
     967       171620 :    do ilm=1,lm_size
     968       160900 :      il = ilang(ilm)
     969       160900 :      ll = ilang(ilm) - 1
     970       160900 :      mm = ilm - (ll+1)**2 + ll
     971              : 
     972       160900 :      select case (rc_ylm)
     973              :      case (1)
     974              :        ! to get PDOS for real spherical harmonics, simply multiply here by ylm_k
     975         2750 :        do ispinor=1,my_nspinor
     976       497025 :          do ipw=1,npw_k
     977       495650 :            tmppsim(ipw,ispinor) = tmppsia(ipw,ispinor) * ylm_k(ipw,ilm)
     978              :          end do
     979              :        end do
     980              : 
     981              :        ! Handle time-reversal
     982              :        ! TODO: check if time reversal with spinors is special and may need some treatment.
     983              :        !  normally SOC will simply impose istwfk 1 in appropriate cases (kptopt 4).
     984         1375 :        if (istwfk /= 1) then
     985          400 :          if (mod(ll, 2) == 0) then
     986        64485 :             tmppsim(:,:) = dcmplx(real(tmppsim(:,:)),zero)
     987              :          else
     988        42990 :             tmppsim(:,:) = dcmplx(aimag(tmppsim(:,:)),zero)
     989              :          end if
     990              : ! f2008 version:
     991              : !         if (mod(ll, 2) == 0) then
     992              : !            tmppsim(:,:)%im = zero
     993              : !         else
     994              : !            tmppsim(:,:)%re = tmppsim(:,:)%im
     995              : !            tmppsim(:,:)%im = zero
     996              : !         end if
     997              :        end if
     998              : 
     999              :      case (2)
    1000              :        ! to get PDOS for complex spherical harmonics, build linear combination of real ylm_k
    1001       159525 :        jlm = (ll+1)**2-ll-mm ! index of (l, -m)
    1002       159525 :        if (mm == 0) then
    1003      5975930 :          vect(:) = dcmplx(ylm_k(1:npw_k,ilm),zero)
    1004       127620 :        else if (mm > 0) then
    1005              :           !vect(1,:) =  invsqrt2 * ylm_k(1:npw_k,ilm) * (-1)**mm
    1006              :           !vect(2,:) = +invsqrt2 * ylm_k(1:npw_k,jlm) * (-1)**mm
    1007        63810 :           c1 = sy(ll, mm, mm)
    1008        63810 :           c2 = sy(ll,-mm, mm)
    1009              :           vect(:) = dcmplx(c1(1) * ylm_k(1:npw_k,ilm) + c2(1) * ylm_k(1:npw_k,jlm), &
    1010     11951860 :                           c1(2) * ylm_k(1:npw_k,ilm) + c2(2) * ylm_k(1:npw_k,jlm))
    1011              : 
    1012              :        else if (mm < 0) then
    1013              :           !vect(1,:) =  invsqrt2 * ylm_k(1:npw_k,jlm) !* (-1)**mm
    1014              :           !vect(2,:) = -invsqrt2 * ylm_k(1:npw_k,ilm) !* (-1)**mm
    1015        63810 :           c1 = sy(ll, mm,  mm)
    1016        63810 :           c2 = sy(ll,-mm,  mm)
    1017              :           vect(:) = dcmplx(c1(1) * ylm_k(1:npw_k,ilm) + c2(1) * ylm_k(1:npw_k,jlm),&
    1018     11951860 :                           c1(2) * ylm_k(1:npw_k,ilm) + c2(2) * ylm_k(1:npw_k,jlm))
    1019              :        end if
    1020     29879650 :        vect(:) = dcmplx(real(vect(:)), -aimag(vect(:)))
    1021              :        !vect(:)%im = -vect(:)%im
    1022              : 
    1023       159525 :        if (istwfk == 1) then
    1024       334700 :          do ispinor=1,my_nspinor
    1025     31602950 :            do ipw=1,npw_k
    1026     31446800 :              tmppsim(ipw,ispinor) = tmppsia(ipw,ispinor) * vect(ipw)
    1027              :            end do
    1028              :          end do
    1029              :        else
    1030              :          ! Handle time-reversal
    1031         3375 :          if (mod(ll, 2) == 0) then
    1032         4050 :            do ispinor=1,my_nspinor
    1033       148215 :              do ipw=1,npw_k
    1034       146190 :                tmppsim(ipw,ispinor) = real(tmppsia(ipw,ispinor)) * vect(ipw)
    1035              :              end do
    1036              :            end do
    1037              :          else
    1038         2700 :            do ispinor=1,my_nspinor
    1039        98810 :              do ipw=1,npw_k
    1040        97460 :                tmppsim(ipw,ispinor) = aimag(tmppsia(ipw,ispinor)) * vect(ipw)
    1041              :              end do
    1042              :            end do
    1043              :          end if
    1044              :        end if
    1045              : 
    1046              :      case default
    1047       160900 :        ABI_ERROR("Wrong value for rc_ylm")
    1048              :      end select
    1049              : 
    1050              :      ! Compute integral $ \int_0^{rc} dr r**2 ||\sum_G u(G) Y_LM^*(k+G) e^{i(k+G).Ra} j_L(|k+G| r)||**2 $
    1051              :      ! or more general spinor case integral
    1052              :      !    $ \int_0^{rc} dr r**2 dotc^*_s   \sigma^x_{ss'}   dotc_{s'}
    1053              :      ! where   dotc_s = \sum_G u_s (G) Y_LM^*(k+G) e^{i(k+G).Ra} j_L(|k+G| r)
    1054     64389286 :      do ixint=1,nradint(iat)
    1055    134103100 :        dotc = czero
    1056    134103100 :        do ispinor=1, my_nspinor
    1057  16359986925 :          do ipw=1,npw_k
    1058  16295764975 :            dotc(ispinor) = dotc(ispinor) + bess_fit(ipw, ixint, il) * tmppsim(ipw, ispinor)
    1059              :          end do
    1060              :        end do
    1061     64221950 :        if (istwfk /= 1) then
    1062      2813950 :          dotc = two * dotc
    1063      1406975 :          if (istwfk == 2 .and. mpi_enreg%me_g0 == 1) then
    1064       876700 :            dotc(:) = dotc(:) - bess_fit(1, ixint, il) * tmppsim(1, :)
    1065              :          end if
    1066              :        end if
    1067              : 
    1068              :        ! Store results to reduce number of xmpi_sum calls if MPI
    1069    134264000 :        do ispinor=1, my_nspinor
    1070    134103100 :          values(ixint, ispinors(ispinor), ilm, iat) = dotc(ispinor)
    1071              :        end do
    1072              :      end do ! ixint
    1073              : 
    1074              :    end do ! ilm
    1075              :  end do ! iat
    1076              : 
    1077         4284 :  ABI_FREE(tmppsia)
    1078         4284 :  ABI_FREE(tmppsim)
    1079         4284 :  ABI_FREE(dotc)
    1080         4284 :  ABI_FREE(ispinors)
    1081              : 
    1082              :  ! Collect results in comm_pw (data are distributed over plane waves)
    1083         4284 :  call xmpi_sum(values, mpi_enreg%comm_bandfft, ierr)
    1084              : ! ! Collect results in mpi_enreg%comm_spinor (data are distributed over spinor components)
    1085         4284 :  call xmpi_sum(values, mpi_enreg%comm_spinor, ierr)
    1086              : 
    1087              :  ! Multiply by r**2 and take norm, integrate
    1088        10720 :  do iat=1,natsph
    1089         6436 :    itypat = typat_extra(iat)
    1090         6436 :    lm_size = mlang_type(itypat) ** 2
    1091       171620 :    do ilm=1,lm_size
    1092              : 
    1093       509000 :      do ipauli=0,nspinor**2-1
    1094    111067650 :        do ixint=1,nradint(iat)
    1095    110719550 :          func(ixint) = zero
    1096    283435900 :          do is=1,nspinor
    1097    580145850 :            do isp=1,nspinor
    1098              :              func(ixint) =  func(ixint) + real(conjg(values(ixint, is, ilm, iat)) * pauli_mat(is,isp,ipauli)*&
    1099    469426300 : &                                                    values(ixint, isp, ilm, iat))
    1100              :            end do
    1101              :          end do
    1102    111067650 :          func(ixint) = rint(ixint)**2 * func(ixint)
    1103              :        end do
    1104              :        ! Here I should treat the case in which the last point /= rcut
    1105              :        ! NB: indexing is from 1 not 0 for spin matrix components
    1106       509000 :        sum_1lm_1atom   (ipauli+1, ilm, iat) = simpson(dr, func(1:nradint(iat)))
    1107              :      end do ! ipauli
    1108              : 
    1109       390636 :      do is = 1, nspinor
    1110     81456450 :        func_cplx(:,1) = real(values(:, is, ilm, iat))
    1111     81456450 :        func_cplx(:,2) = aimag(values(:, is, ilm, iat))
    1112     79944450 :        do ixint=1,nradint(iat)
    1113    239386750 :          func_cplx(ixint,:) = rint(ixint)**2 * func_cplx(ixint,:)
    1114              :        end do
    1115       223300 :        cplx_1lm_1atom(1, is, ilm, iat) = simpson(dr, func_cplx(1:nradint(iat),1))
    1116       384200 :        cplx_1lm_1atom(2, is, ilm, iat) = simpson(dr, func_cplx(1:nradint(iat),2))
    1117              :      end do
    1118              : 
    1119              :    end do ! ilm
    1120              :  end do ! iat
    1121              : 
    1122              :  ! Normalize with unit cell volume and include 4pi term coming from Rayleigh expansion.
    1123         4284 :  fact = four_pi**2 / ucvol
    1124       519720 :  sum_1lm_1atom = fact * sum_1lm_1atom
    1125       841520 :  cplx_1lm_1atom = fact * cplx_1lm_1atom
    1126              : 
    1127              :  ! sum up the m-independent fractions
    1128       112520 :  sum_1ll_1atom = zero
    1129        10720 :  do iat=1,natsph
    1130         6436 :    itypat = typat_extra(iat)
    1131         6436 :    lm_size = mlang_type(itypat) ** 2
    1132       171620 :    do ilm=1,lm_size
    1133       160900 :      il = ilang(ilm)
    1134       515436 :      sum_1ll_1atom(:,il, iat) = sum_1ll_1atom(:,il, iat) + sum_1lm_1atom(:,ilm, iat)
    1135              :    end do
    1136              :  end do
    1137              : 
    1138         4284 :  ABI_FREE(values)
    1139              : 
    1140              :  ! Output
    1141         8568 :  if (prtsphere == 1) then
    1142          240 :    sum_1ll = zero
    1143         1040 :    sum_1lm = zero
    1144           95 :    sum_1atom = zero
    1145           95 :    do iat=1,natsph
    1146         1430 :      sum_1atom(iat) = sum(sum_1lm_1atom(1,:,iat))
    1147          330 :      sum_1ll(:)=sum_1ll(:)+sum_1ll_1atom(1,:,iat)
    1148         1470 :      sum_1lm(:)=sum_1lm(:)+sum_1lm_1atom(1,:,iat)
    1149              :    end do
    1150           95 :    sum_all = sum(sum_1atom)
    1151              : 
    1152           40 :    if (rc_ylm == 1) msg = " Angular analysis (real spherical harmonics)"
    1153           40 :    if (rc_ylm == 2) msg = " Angular analysis (complex spherical harmonics)"
    1154           40 :    call wrtout(std_out, msg)
    1155           95 :    do iat=1,natsph
    1156           55 :      call atomdata_from_znucl(atom, znucl_sph(iat))
    1157           55 :      call wrtout(std_out, " ")
    1158           55 :      write(msg,'(a,i3,a,a,a,f10.6)' )' Atom # ',iat, ' is  ',  atom%symbol,', in-sphere charge =',sum_1atom(iat)
    1159           55 :      call wrtout(std_out, msg)
    1160          425 :      do ll=0,mlang-1
    1161              :        write(msg,'(a,i1,a,f9.6,a,9f6.3)' )&
    1162          275 :         ' l=',ll,', charge=',sum_1ll_1atom(1,ll+1,iat),&
    1163          550 :         ', m=-l,l splitting:',sum_1lm_1atom(1,1+ll**2:(ll+1)**2,iat)
    1164          330 :        call wrtout(std_out, msg)
    1165              :      end do ! ll
    1166              :    end do ! iat
    1167           40 :    write(msg,'(a,a)') ch10,' Sum of angular contributions for all atomic spheres '
    1168           40 :    call wrtout(std_out, msg)
    1169          240 :    do ll=0,mlang-1
    1170              :      write(msg,'(a,i1,a,f9.6,a,f9.6)' )&
    1171          200 :       ' l=',ll,', charge =',sum_1ll(ll+1),' proportion =',sum_1ll(ll+1)/sum_all
    1172          240 :      call wrtout(std_out, msg)
    1173              :    end do
    1174           40 :    write(msg,'(a,a,f10.6)' ) ch10,' Total over all atoms and l=0 to 4 :',sum_all
    1175           40 :    call wrtout(std_out, msg)
    1176           40 :    call wrtout(std_out, " ")
    1177              :  end if
    1178              : 
    1179              : contains
    1180              : 
    1181       255240 :  function sy(ll, mm, mp)
    1182              :    use  m_paw_sphharm, only : ys
    1183              :    ! Computes the matrix element <Slm|Ylm'>
    1184              :    integer,intent(in) :: ll,mm, mp
    1185              : 
    1186              :    real(dp) :: sy(2)
    1187              :    complex(dp) :: ys_val
    1188              : 
    1189              :    ! Computes the matrix element <Yl'm'|Slm>
    1190       255240 :    call ys(ll,mp,ll,mm,ys_val)
    1191              :    !call ys(ll,mm,ll,mp,ys_val)
    1192       255240 :    sy(1) = real(ys_val)
    1193       255240 :    sy(2) = -aimag(ys_val)
    1194              : 
    1195              :  end function sy
    1196              : 
    1197              : end subroutine recip_ylm
    1198              : !!***
    1199              : 
    1200              : !!****f* m_epjdos/dens_in_sph
    1201              : !! NAME
    1202              : !! dens_in_sph
    1203              : !!
    1204              : !! FUNCTION
    1205              : !!  Calculate integrated density in sphere around each atom
    1206              : !!
    1207              : !! INPUTS
    1208              : !!  cg      = wavefunction coefficitents in recip space
    1209              : !!  gmet    = metric in recip space
    1210              : !!  istwfk  = storage mode for cg coefficients
    1211              : !!  kg_k    = G vector indices
    1212              : !!  natom   = number of atoms
    1213              : !!  mpi_enreg=information about MPI parallelization
    1214              : !!  ngfft(18)=contain all needed information about 3D FFT, see ~abinit/doc/variables/vargs.htm#ngfft
    1215              : !!  npw_k   = number of plane waves for this kpoint
    1216              : !!  ph1d    = phase factors for different atoms for all G vectors
    1217              : !!  rmax(natom) = max radius to integrate to (in bohr)
    1218              : !!
    1219              : !! OUTPUT
    1220              : !!  cmax = integrated density for each atom for a rmax-radius sphere
    1221              : !!
    1222              : !! WARNING
    1223              : !!  cg should not be modified by fourwf.
    1224              : !!
    1225              : !! SOURCE
    1226              : 
    1227           40 : subroutine dens_in_sph(cmax,cg,gmet,istwfk,kg_k,natom,ngfft,mpi_enreg,npw_k,&
    1228           40 : &                       ph1d,rmax,ucvol)
    1229              : 
    1230              : !Arguments ------------------------------------
    1231              : !scalars
    1232              :  integer,intent(in) :: istwfk,natom,npw_k
    1233              :  real(dp),intent(in) :: ucvol
    1234              :  type(MPI_type),intent(in) :: mpi_enreg
    1235              : !arrays
    1236              :  integer,intent(in) :: kg_k(3,npw_k),ngfft(18)
    1237              :  real(dp),intent(in) :: gmet(3,3)
    1238              :  real(dp),intent(in) :: ph1d(2,(2*ngfft(1)+1+2*ngfft(2)+1+2*ngfft(3)+1)*natom)
    1239              :  real(dp),intent(in) :: rmax(natom)
    1240              :  real(dp),intent(inout) :: cg(2,npw_k)
    1241              :  real(dp),intent(out) :: cmax(natom)
    1242              : 
    1243              : !Local variables -------------------------
    1244              : !scalars
    1245              :  integer,parameter :: tim_fourwf=0
    1246              :  integer :: cplex,i1,i2,i3,iatom,id1,id2,id3,ifft,mgfft,n1,n2,n3,n4,n5,n6,nfft,nfftot
    1247              :  real(dp) :: cmaxr,g1,g2,g3,norm,weight
    1248              : !arrays
    1249              :  integer :: ngfft_here(18)
    1250           40 :  integer,allocatable :: garr(:,:),gbound(:,:)
    1251           40 :  real(dp),allocatable :: denpot(:,:,:),fofgout(:,:),fofr(:,:,:,:),gnorm(:)
    1252           40 :  real(dp),allocatable :: ph3d(:,:,:),phkxred(:,:),rhog(:,:),rhor(:), sphrhog(:,:)
    1253              : ! *********************************************************************
    1254              : 
    1255           40 :  n1=ngfft(1)
    1256           40 :  n2=ngfft(2)
    1257           40 :  n3=ngfft(3)
    1258           40 :  n4=ngfft(4)
    1259           40 :  n5=ngfft(5)
    1260           40 :  n6=ngfft(6)
    1261           40 :  nfftot = n1*n2*n3
    1262           40 :  nfft=n1*n2*n3
    1263           40 :  ngfft_here(:) = ngfft(:)
    1264              : !fourwf doesnt work with other options for mode 0 (fft G -> r)
    1265           40 :  ngfft_here(7)=111
    1266           40 :  ngfft_here(8)=256
    1267          160 :  mgfft=maxval(ngfft_here(1:3))
    1268              : 
    1269           40 :  call sqnorm_g(norm,istwfk,npw_k,cg,mpi_enreg%me_g0,mpi_enreg%comm_fft)
    1270              : 
    1271           40 :  if (abs(one-norm) > tol6) then
    1272            0 :    write(std_out,'(a,f8.5)' ) ' dens_in_sph : this state is not normalized : norm=',norm
    1273              :  end if
    1274              : 
    1275              : !-----------------------------------------------------------------
    1276              : !inverse FFT of wavefunction to real space => density in real space
    1277              : !-----------------------------------------------------------------
    1278          160 :  ABI_MALLOC(gbound,(2*mgfft+8,2))
    1279           40 :  call sphereboundary(gbound,istwfk,kg_k,mgfft,npw_k)
    1280              : 
    1281           40 :  weight = one
    1282           40 :  cplex=1
    1283          200 :  ABI_MALLOC(denpot,(cplex*n4,n5,n6))
    1284       500360 :  denpot(:,:,:)=zero
    1285          120 :  ABI_MALLOC(fofgout,(2,npw_k))
    1286          200 :  ABI_MALLOC(fofr,(2,n4,n5,n6))
    1287              : 
    1288              :  call fourwf(cplex,denpot,cg,fofgout,fofr,gbound,gbound, &
    1289              :    istwfk,kg_k,kg_k,mgfft,mpi_enreg,1,ngfft_here,npw_k,&
    1290           40 :    npw_k,n4,n5,n6,1,tim_fourwf,weight,weight)
    1291              : 
    1292           40 :  ABI_FREE(fofgout)
    1293           40 :  ABI_FREE(fofr)
    1294           40 :  ABI_FREE(gbound)
    1295              : 
    1296       500360 :  norm = sum(denpot(:,:,:))/nfftot
    1297           40 :  if (abs(one-norm) > tol6) then
    1298            0 :    write(std_out,'(a,f8.5)') ' dens_in_sph : this state is not normalized in real space : norm=',norm
    1299              :  end if
    1300              : 
    1301              : !-----------------------------------------------------------------
    1302              : !FFT of new density: we obtain n(G) in rhog(1,:)
    1303              : !-----------------------------------------------------------------
    1304              : 
    1305              : !Change the packing of the reciprocal space density
    1306          120 :  ABI_MALLOC(rhor,(nfft))
    1307           40 :  call fftpac(1,mpi_enreg,1,n1,n2,n3,n4,n5,n6,ngfft,rhor,denpot,1)
    1308              : 
    1309          120 :  ABI_MALLOC(rhog,(2,nfft))
    1310           40 :  call fourdp(1,rhog,rhor,-1,mpi_enreg,nfft,1,ngfft,0)
    1311              : 
    1312           40 :  ABI_FREE(rhor)
    1313           40 :  ABI_FREE(denpot)
    1314              : 
    1315       439208 :  do ifft=1,nfft
    1316      1317544 :    rhog(:,ifft) = rhog(:,ifft) / ucvol
    1317              :  end do
    1318              : 
    1319              : !-----------------------------------------------------------------
    1320              : !calculate norms of G vectors
    1321              : !-----------------------------------------------------------------
    1322              : 
    1323          120 :  ABI_MALLOC(garr,(3,nfft))
    1324           80 :  ABI_MALLOC(gnorm,(nfft))
    1325           40 :  id3=ngfft(3)/2+2 ; id2=ngfft(2)/2+2 ; id1=ngfft(1)/2+2
    1326          920 :  do i3=1,n3
    1327          880 :    g3=i3-(i3/(id3))*ngfft(3)-one
    1328        20472 :    do i2=1,n2
    1329        19552 :      g2=i2-(i2/(id2))*ngfft(2)-one
    1330       459600 :      do i1=1,n1
    1331       439168 :        g1=i1-(i1/(id1))*ngfft(1)-one
    1332       439168 :        ifft=i1+(i2-1)*n1+(i3-1)*n1*n2
    1333       439168 :        garr(1,ifft)=nint(g1)
    1334       439168 :        garr(2,ifft)=nint(g2)
    1335       439168 :        garr(3,ifft)=nint(g3)
    1336              :        gnorm(ifft)=sqrt(gmet(1,1)*g1*g1 + &
    1337              : &       two*gmet(2,1)*g2*g1 + &
    1338              : &       two*gmet(3,1)*g3*g1 + &
    1339              : &       gmet(2,2)*g2*g2 + &
    1340              : &       gmet(3,2)*g3*g2 + &
    1341       458720 : &       gmet(3,3)*g3*g3)
    1342              :      end do
    1343              :    end do
    1344              :  end do
    1345              : 
    1346              : !-----------------------------------------------------------------
    1347              : !For each atom call sphericaldens to calculate
    1348              : !n(G) * 1/|G|^3  *  int_0^2*\pi*r_{max}*|G| 4 \pi y^2 j_0 (y) dy
    1349              : !for all G vectors put into array sphrhog
    1350              : !scalar product of phase factors with spherically convoluted density
    1351              : !-----------------------------------------------------------------
    1352              : 
    1353              : !largest mem occupation = nfft * (2(sphrog) +2*1(ph3d) +3(garr) +2(rhog) +1(gnorm)) = nfft * 10
    1354           80 :  ABI_MALLOC(sphrhog,(2,nfft))
    1355          120 :  ABI_MALLOC(phkxred,(2,natom))
    1356           95 :  phkxred(1,:)=one
    1357           95 :  phkxred(2,:)=zero
    1358           80 :  ABI_MALLOC(ph3d,(2,nfft,1))
    1359              : 
    1360           95 :  do iatom=1,natom
    1361              : 
    1362           55 :    call sphericaldens(rhog,gnorm,nfft,rmax(iatom),sphrhog)
    1363              : !  -----------------------------------------------------------------
    1364              : !  Compute the phases for the whole set of fft vectors
    1365              : !  -----------------------------------------------------------------
    1366              : 
    1367           55 :    call ph1d3d(iatom,iatom,garr,natom,natom,nfft,ngfft(1),ngfft(2),ngfft(3),phkxred,ph1d,ph3d)
    1368              : 
    1369              : !  For the phase factors, take the compex conjugate, before evaluating the scalar product
    1370       542519 :    do ifft=1,nfft
    1371       542519 :      ph3d(2,ifft,1)=-ph3d(2,ifft,1)
    1372              :    end do
    1373           55 :    cplex=2
    1374           55 :    call dotprod_v(cplex,cmaxr,nfft,1,0,ph3d,sphrhog,mpi_enreg%comm_fft)
    1375           95 :    cmax(iatom) = cmaxr
    1376              : !  write(std_out,'(a,i4,a,es14.6,a,es12.6)' )' dens_in_sph : At ', iatom, ' has ',cmaxr, ' el.s in a sphere of rad ', rmax
    1377              :  end do
    1378              : 
    1379           40 :  ABI_FREE(rhog)
    1380           40 :  ABI_FREE(gnorm)
    1381           40 :  ABI_FREE(garr)
    1382           40 :  ABI_FREE(sphrhog)
    1383           40 :  ABI_FREE(ph3d)
    1384           40 :  ABI_FREE(phkxred)
    1385              : 
    1386           40 : end subroutine dens_in_sph
    1387              : !!***
    1388              : 
    1389              : !!****f* m_epjdos/sphericaldens
    1390              : !! NAME
    1391              : !! sphericaldens
    1392              : !!
    1393              : !! FUNCTION
    1394              : !! Compute the convolution of a function with
    1395              : !! the unity constant function over a sphere of radius rmax .
    1396              : !! The function is to be given in reciprocal space,
    1397              : !! the resulting function is also given in reciprocal space.
    1398              : !! The routine needs the norm of the reciprocal space vectors.
    1399              : !!
    1400              : !! The resulting function in reciprocal space can give the
    1401              : !! integral of the density in any sphere of that radius, centered
    1402              : !! on any point, by a simple scalar product.
    1403              : !!
    1404              : !! INPUTS
    1405              : !!  fofg(2,nfft)=initial function, in reciprocal space
    1406              : !!  gnorm(nfft)=norm of the reciprocal space vectors
    1407              : !!  nfft=(effective) number of FFT grid points (for this processor)
    1408              : !!  rmax=radius of the sphere
    1409              : !!
    1410              : !! OUTPUT
    1411              : !!  sphfofg(2,nfft)=convoluted function, in reciprocal space
    1412              : !!
    1413              : !! SOURCE
    1414              : 
    1415           55 : subroutine sphericaldens(fofg,gnorm,nfft,rmax,sphfofg)
    1416              : 
    1417              : !Arguments ------------------------------------
    1418              : !scalars
    1419              :  integer,intent(in) :: nfft
    1420              :  real(dp),intent(in) :: rmax
    1421              : !arrays
    1422              :  real(dp),intent(in) :: fofg(2,nfft),gnorm(nfft)
    1423              :  real(dp),intent(out) :: sphfofg(2,nfft)
    1424              : 
    1425              : !Local variables-------------------------------
    1426              : !scalars
    1427              :  integer :: ifft
    1428              :  real(dp) :: factor,int0yy,rmax_2pi,yy
    1429              : ! *************************************************************************
    1430              : 
    1431           55 :  rmax_2pi=two_pi*rmax
    1432           55 :  factor=four_pi/(two_pi)**3
    1433              : 
    1434       542519 :  do ifft=1,nfft
    1435       542519 :    if(abs(gnorm(ifft)) < tol12)then
    1436           55 :      sphfofg(1,ifft)=fofg(1,ifft)*four_pi*third*rmax**3
    1437           55 :      sphfofg(2,ifft)=fofg(2,ifft)*four_pi*third*rmax**3
    1438              :    else
    1439       542409 :      yy=gnorm(ifft)*rmax_2pi
    1440       542409 :      int0yy=factor*(sin(yy)-yy*cos(yy))/(gnorm(ifft)**3)
    1441       542409 :      sphfofg(1,ifft)=fofg(1,ifft)*int0yy
    1442       542409 :      sphfofg(2,ifft)=fofg(2,ifft)*int0yy
    1443              :    end if
    1444              :  end do
    1445              : 
    1446           55 : end subroutine sphericaldens
    1447              : !!***
    1448              : 
    1449              : !!****f* m_epjdos/epjdos_prtfatbands
    1450              : !! NAME
    1451              : !! epjdos_prtfatbands
    1452              : !!
    1453              : !! FUNCTION
    1454              : !! Print dos_fractions_m in order to plot easily fatbands
    1455              : !! if pawfatbnd=1  1 : fatbands are resolved in L.
    1456              : !! if pawfatbnd=1  2 : fatbands are resolved in L and M.
    1457              : !!
    1458              : !! INPUTS
    1459              : !!  dos_fractions_m(nkpt,mband,nsppol,ndosfraction*mbesslang*m_dos_flag)
    1460              : !!               = m-resolved projected dos inside PAW sphere.
    1461              : !!  dtset        = Input variables
    1462              : !!  ebands<ebands_t>=Band structure data.
    1463              : !!  pawfatbnd    = keyword for fatbands
    1464              : !!  mbesslang    =maximum angular momentum for Bessel function expansion
    1465              : !!  m_dos_flag   =option for the m-contributions to the partial DOS
    1466              : !!  ndosfraction =natsph*mbesslang
    1467              : !!
    1468              : !! OUTPUT
    1469              : !! (only writing)
    1470              : !!
    1471              : !! NOTES
    1472              : !!  This routine should be called by master only
    1473              : !!
    1474              : !! SOURCE
    1475              : 
    1476            1 : subroutine epjdos_prtfatbands(dos,dtset,ebands,fildata,pawfatbnd,pawtab)
    1477              : 
    1478              : !Arguments ------------------------------------
    1479              : !scalars
    1480              :  class(epjdos_t),intent(in) :: dos
    1481              :  integer,intent(in) :: pawfatbnd
    1482              :  type(ebands_t),intent(in) :: ebands
    1483              :  type(dataset_type),intent(in) :: dtset
    1484              :  character(len=fnlen),intent(in) :: fildata
    1485              : !arrays
    1486              :  type(pawtab_type),intent(in) :: pawtab(dtset%ntypat)
    1487              : 
    1488              : !Local variables-------------------------------
    1489              : !scalars
    1490              :  integer :: iall,il,iat,natsph,inbfatbands,iband,mband,ixfat,isppol,nkpt,lmax,ll,mm
    1491              :  integer :: ikpt,nband_k,ndosfraction,mbesslang
    1492              :  real(dp) :: xfatband,cpu,wall,gflops
    1493              :  character(len=1) :: tag_l,tag_1m,tag_is
    1494              :  character(len=2) :: tag_2m
    1495              :  character(len=10) :: tag_il,tag_at,tag_grace
    1496              :  character(len=1500) :: msg
    1497              :  character(len=fnlen) :: tmpfil
    1498              :  type(atomdata_t) :: atom
    1499              : !arrays
    1500              :  integer :: units(2)
    1501            1 :  integer,allocatable :: unitfatbands_arr(:,:)
    1502            1 :  real(dp),allocatable :: eigenvalues(:,:,:)
    1503              :  character(len=2) :: symbol
    1504              : !*************************************************************************
    1505              : 
    1506              :  DBG_ENTER("COLL")
    1507              : 
    1508            3 :  units = [std_out, ab_out]
    1509            1 :  ndosfraction = dos%ndosfraction; mbesslang = dos%mbesslang
    1510              : 
    1511            1 :  if(dos%prtdosm.ne.0) then
    1512              :    write(msg,'(3a)')&
    1513            0 :     'm decomposed dos is activated',ch10, &
    1514            0 :     'Action: deactivate it with prtdosm=0 !'
    1515            0 :    ABI_ERROR(msg)
    1516              :  end if
    1517              : 
    1518            1 :  if(dtset%nspinor==2) then
    1519            0 :    ABI_WARNING("Fatbands are not yet available in the case nspinor==2!")
    1520              :  end if
    1521              : 
    1522            1 :  ABI_CHECK(allocated(dos%fractions_m), "dos%fractions_m is not allocated!")
    1523              : 
    1524            1 :  natsph=dtset%natsph
    1525            1 :  nkpt=dtset%nkpt
    1526            1 :  mband=dtset%mband
    1527              : 
    1528            1 :  if(natsph>1000) then
    1529              :    write(msg,'(3a)')&
    1530            0 :     'Too big number of fat bands!',ch10, &
    1531            0 :     'Action: decrease natsph in input file !'
    1532            0 :    ABI_ERROR(msg)
    1533              :  end if
    1534              : 
    1535              : !--------------  PRINTING IN LOG
    1536            1 :  call cwtime(cpu, wall, gflops, "start")
    1537            1 :  write(msg,'(a,a,a,a,i5,a,a,1000i5)') ch10," ***** Print of fatbands activated ****** ",ch10,&
    1538            1 :   "  Number of atom: natsph = ",natsph,ch10, &
    1539            6 :   "  atoms  are             = ",(dtset%iatsph(iat),iat=1,natsph)
    1540            1 :  call wrtout(units, msg)
    1541            1 :  iall=0;inbfatbands=0
    1542              : 
    1543            1 :  if(pawfatbnd==1) then
    1544            0 :    inbfatbands=mbesslang-1
    1545            0 :    write(msg,'(3a)')"  (fatbands are in eV and are given for each value of L)",ch10
    1546            1 :  else if(pawfatbnd==2) then
    1547            1 :    write(msg,'(3a)')"  (fatbands are in eV and are given for each value of L and M)",ch10
    1548            1 :    inbfatbands=(mbesslang-1)**2
    1549              :  end if
    1550            1 :  call wrtout(units, msg)
    1551              : 
    1552            1 :  write(msg,'(a,e12.5,a,e12.5,a)') "  Fermi energy is ",ebands%fermie*Ha_eV," eV = ",ebands%fermie," Ha"
    1553            1 :  call wrtout(std_out,msg)
    1554              : 
    1555              : !--------------  OPEN AND NAME FILES FOR FATBANDS
    1556            4 :  ABI_MALLOC(unitfatbands_arr,(natsph*inbfatbands,dtset%nsppol))
    1557           66 :  unitfatbands_arr = -3
    1558              : 
    1559            5 :  do iat=1,natsph
    1560            4 :    lmax=(pawtab(dtset%typat(dtset%iatsph(iat)))%l_size-1)/2
    1561            4 :    call int2char4(dtset%iatsph(iat),tag_at)
    1562            4 :    ABI_CHECK((tag_at(1:1)/='#'),'Bug: string length too short!')
    1563            4 :    call atomdata_from_znucl(atom,dtset%znucl(dtset%typat(dtset%iatsph(iat))))
    1564            4 :    symbol = atom%symbol
    1565           69 :    do il=1,inbfatbands
    1566           64 :      iall=iall+1
    1567           64 :      ll=int(sqrt(float(il-1)))  ! compute l
    1568           68 :      if(ll.le.lmax) then  ! print only angular momentum included in the PAW data
    1569           72 :        do isppol=1,dtset%nsppol
    1570           36 :          write(tag_is,'(i1)')isppol
    1571           36 :          if(pawfatbnd==1) then
    1572            0 :            call int2char4(il-1,tag_il)
    1573            0 :            ABI_CHECK((tag_il(1:1)/='#'),'Bug: string length too short!')
    1574            0 :            tmpfil = trim(fildata)//'_at'//trim(tag_at)//'_'//trim(adjustl(symbol))//'_is'//tag_is//'_l'//trim(tag_il)
    1575           36 :          else if (pawfatbnd==2) then
    1576           36 :            write(tag_l,'(i1)') ll
    1577           36 :            mm=il-(ll**2+ll+1)      ! compute m
    1578           36 :            if(mm<0) write(tag_2m,'(i2)') mm
    1579           36 :            if(mm>=0) write(tag_1m,'(i1)') mm
    1580           36 :            if(mm<0) tmpfil = trim(fildata)// &
    1581           12 : &           '_at'//trim(tag_at)//'_'//trim(adjustl(symbol))//'_is'//tag_is//'_l'//tag_l//'_m'//tag_2m
    1582           36 :            if(mm>=0) tmpfil = trim(fildata)// &
    1583           24 : &           '_at'//trim(tag_at)//'_'//trim(adjustl(symbol))//'_is'//tag_is//'_l'//tag_l//'_m+'//tag_1m
    1584              :          end if
    1585              :          !unitfatbands_arr(iall,isppol)=tmp_unit+100+iall-1+(natsph*inbfatbands)*(isppol-1)
    1586              :          !open (unit=unitfatbands_arr(iall,isppol),file=trim(tmpfil),status='unknown',form='formatted')
    1587           36 :          if (open_file(tmpfil, msg, newunit=unitfatbands_arr(iall,isppol), status='unknown',form='formatted') /= 0) then
    1588            0 :            ABI_ERROR(msg)
    1589              :          end if
    1590              : 
    1591           36 :          write(msg,'(a,a,a,i4)') 'opened file : ', trim(tmpfil), ' unit', unitfatbands_arr(iall,isppol)
    1592           36 :          call wrtout(std_out,msg)
    1593           36 :          write(msg,'(9a)') "# ",ch10,"# ABINIT package : FATBAND file ", ch10,&
    1594           36 :            "# It contains, for each band: the eigenvalues in eV (and the character of the band) as a function of the k-point",&
    1595           72 :            ch10,"# This file can be read with xmgrace (http://plasma-gate.weizmann.ac.il/Grace/)  ",ch10,"#  "
    1596           36 :          write(unitfatbands_arr(iall,isppol), "(a)")trim(msg)
    1597         1116 :          do iband=1,mband
    1598         1080 :            call int2char4(iband-1,tag_grace)
    1599         1080 :            ABI_CHECK((tag_grace(1:1)/='#'),'Bug: string length too short!')
    1600         1080 :            write(msg,'(16a)') ch10,"@    s",trim(tag_grace)," line color 1",&
    1601         1080 :             ch10,"@    s",trim(tag_grace)," errorbar color 2",&
    1602         1080 :             ch10,"@    s",trim(tag_grace)," errorbar riser linewidth 5.0", &
    1603         2160 :             ch10,"@    s",trim(tag_grace)," errorbar linestyle 0"
    1604         1116 :            write(unitfatbands_arr(iall,isppol), "(a)")trim(msg)
    1605              :          end do  !iband
    1606           72 :          write(unitfatbands_arr(iall,isppol), '(a,a)') ch10,'@type xydy'
    1607              :        end do   ! isppol
    1608              :      end if ! ll=<lmax
    1609              :    end do   ! il
    1610              :  end do  ! iat
    1611              : 
    1612            1 :  if(iall.ne.(natsph*inbfatbands)) then
    1613            0 :    ABI_ERROR("error1 ")
    1614              :  end if
    1615              : 
    1616              : !--------------  WRITE FATBANDS IN FILES
    1617            1 :  if (pawfatbnd>0) then
    1618              :    ! Store eigenvalues with nkpt as first dimension for efficiency reasons
    1619            5 :    ABI_MALLOC(eigenvalues,(nkpt,mband,dtset%nsppol))
    1620            2 :    do isppol=1,dtset%nsppol
    1621           18 :      do ikpt=1,nkpt
    1622           16 :        nband_k=dtset%nband(ikpt+(isppol-1)*nkpt)
    1623          497 :        do iband=1,mband
    1624          496 :          eigenvalues(ikpt,iband,isppol)= ebands%eig(iband, ikpt, isppol) - ebands%fermie
    1625              :        end do
    1626              :      end do
    1627              :    end do
    1628            1 :    iall=0
    1629            5 :    do iat=1,natsph
    1630            4 :      lmax=(pawtab(dtset%typat(dtset%iatsph(iat)))%l_size-1)/2
    1631           69 :      do il=1,inbfatbands
    1632           64 :        iall=iall+1
    1633           64 :        ll=int(sqrt(float(il-1)))
    1634           68 :        if(ll.le.lmax) then
    1635           72 :          do isppol=1,dtset%nsppol
    1636         1116 :            do iband=1,mband
    1637         1080 :              write(unitfatbands_arr(iall,isppol),'(a,a,i8)') ch10,"# BAND number :",iband
    1638        18396 :              do ikpt=1,nkpt
    1639        17280 :                if(pawfatbnd==1) then
    1640            0 :                  xfatband=0.d0
    1641            0 :                  do ixfat=(il-1)**2+1,il**2
    1642            0 :                    xfatband=xfatband+dos%fractions_m(ikpt,iband,isppol,(iat-1)*mbesslang**2+ixfat)
    1643              :                  end do ! ixfat
    1644        17280 :                else if (pawfatbnd==2) then
    1645        17280 :                  xfatband=dos%fractions_m(ikpt,iband,isppol,(iat-1)*mbesslang**2+il)
    1646              :                end if
    1647              :                write(unitfatbands_arr(iall,isppol),'(i5,e20.5,e20.5)')&
    1648        18360 :                  ikpt-1,eigenvalues(ikpt,iband,isppol)*Ha_eV,xfatband
    1649              :              end do ! ikpt
    1650              :            end do  !iband
    1651           72 :            write(unitfatbands_arr(iall,isppol),'(a)') '&'
    1652              :            !close(unitfatbands_arr(iall,isppol))
    1653              :          end do  !isppol
    1654              :        end if
    1655              :      end do ! il
    1656              :    end do ! iat
    1657            1 :    ABI_FREE(eigenvalues)
    1658              :  end if
    1659              : 
    1660            2 :  do isppol=1,size(unitfatbands_arr, dim=2)
    1661           66 :    do iat=1,size(unitfatbands_arr, dim=1)
    1662           65 :      if (unitfatbands_arr(iat, isppol) /= -3) close (unitfatbands_arr(iat, isppol))
    1663              :    end do
    1664              :  end do
    1665              : 
    1666            1 :  ABI_FREE(unitfatbands_arr)
    1667              : 
    1668            1 :  call cwtime(cpu,wall,gflops,"stop")
    1669            1 :  write(msg,'(2(a,f8.2),a)')" epjdos_prtfatbands: cpu_time: ",cpu,"[s], walltime: ",wall," [s]"
    1670            1 :  call wrtout(std_out,msg,"PERS")
    1671              : 
    1672              :  DBG_EXIT("COLL")
    1673              : 
    1674            2 : end subroutine epjdos_prtfatbands
    1675              : !!***
    1676              : 
    1677              : !----------------------------------------------------------------------
    1678              : 
    1679              : !!****f* m_epjdos/epjdos_ncwrite
    1680              : !! NAME
    1681              : !! epjdos_ncwrite
    1682              : !!
    1683              : !! FUNCTION
    1684              : !!  Write PJDOS contributions to netcdf file.
    1685              : !!
    1686              : !! INPUTS
    1687              : !!  crystal<crystal_t>=Object defining the unit cell and its symmetries.
    1688              : !!  ebands<ebands_t>=Band structure data.
    1689              : !!  hdr<hdr_t>=Abinit header
    1690              : !!  dtset<dtset_type>=Dataset type
    1691              : !!  psps <type(pseudopotential_type)>=variables related to pseudopotentials
    1692              : !!  pawtab(ntypat*usepaw) <type(pawtab_type)>=paw tabulated starting data
    1693              : !!  ncid=NC file handle.
    1694              : !!
    1695              : !! OUTPUT
    1696              : !!  Only writing
    1697              : !!
    1698              : !! SOURCE
    1699              : 
    1700           28 : subroutine epjdos_ncwrite(dos, crystal, ebands, hdr, dtset, psps, pawtab, ncid)
    1701              : 
    1702              : !Arguments ------------------------------------
    1703              : !scalars
    1704              :  class(epjdos_t),intent(in) :: dos
    1705              :  integer,intent(in) :: ncid
    1706              :  type(crystal_t),intent(in) :: crystal
    1707              :  type(ebands_t),intent(in) :: ebands
    1708              :  type(hdr_type),intent(in) :: hdr
    1709              :  type(dataset_type),intent(in) :: dtset
    1710              :  type(pseudopotential_type),intent(in) :: psps
    1711              : !arrays
    1712              :  type(pawtab_type),intent(in) :: pawtab(dtset%ntypat*dtset%usepaw)
    1713              : 
    1714              : !Local variables-------------------------------
    1715              : !scalars
    1716              :  integer :: itype,ncerr,fform
    1717              :  real(dp) :: cpu,wall,gflops
    1718              :  character(len=500) :: msg
    1719              : !arrays
    1720           56 :  integer :: lmax_type(crystal%ntypat)
    1721              : !*************************************************************************
    1722              : 
    1723           28 :  ABI_CHECK(dtset%natsph > 0, "natsph <=0")
    1724           28 :  call cwtime(cpu, wall, gflops, "start")
    1725              : 
    1726           28 :  fform = fform_from_ext("FATBANDS.nc")
    1727           28 :  ABI_CHECK(fform /= 0, "Cannot find fform associated to FATBANDS.nc")
    1728              : 
    1729              :  ! Write header, crystal structure and band energies.
    1730           28 :  NCF_CHECK(hdr%ncwrite(ncid, fform, nc_define=.True.))
    1731           28 :  NCF_CHECK(crystal%ncwrite(ncid))
    1732           28 :  NCF_CHECK(ebands%ncwrite(ncid))
    1733              : 
    1734              :  ! Add fatband-specific quantities
    1735              :  ncerr = nctk_def_dims(ncid, [ &
    1736              :    nctkdim_t("natsph", dtset%natsph), &
    1737           84 :    nctkdim_t("ndosfraction", dos%ndosfraction)], defmode=.True.)
    1738           28 :  NCF_CHECK(ncerr)
    1739              : 
    1740           28 :  if (dos%ndosfraction*dos%mbesslang > 0) then
    1741              :    ncerr = nctk_def_dims(ncid, [ &
    1742              :      nctkdim_t("mbesslang", dos%mbesslang), &
    1743           72 :      nctkdim_t("dos_fractions_m_lastsize", dos%ndosfraction*dos%mbesslang)])
    1744           24 :    NCF_CHECK(ncerr)
    1745              :  end if
    1746           28 :  if (dtset%natsph_extra /= 0) then
    1747            2 :    NCF_CHECK(nctk_def_dims(ncid, [nctkdim_t("natsph_extra", dtset%natsph_extra)]))
    1748              :  end if
    1749              : 
    1750          112 :  ncerr = nctk_def_iscalars(ncid, [character(len=nctk_slen) :: "prtdos", "pawprtdos", "prtdosm"])
    1751           28 :  NCF_CHECK(ncerr)
    1752           56 :  ncerr = nctk_def_dpscalars(ncid, [character(len=nctk_slen) :: "ratsph_extra"])
    1753           28 :  NCF_CHECK(ncerr)
    1754              : 
    1755              :  ncerr = nctk_def_arrays(ncid, [&
    1756              :    nctkarr_t("lmax_type", "int", "number_of_atom_species"), &
    1757              :    nctkarr_t("iatsph", "int", "natsph"), &
    1758              :    nctkarr_t("ratsph", "dp", "number_of_atom_species"), &
    1759              :    nctkarr_t("dos_fractions", "dp", "number_of_kpoints, max_number_of_states, number_of_spins, ndosfraction") &
    1760          140 :  ])
    1761           28 :  NCF_CHECK(ncerr)
    1762              : 
    1763           28 :  if (allocated(dos%fractions_m)) then
    1764              :    ncerr = nctk_def_arrays(ncid, &
    1765              :      nctkarr_t("dos_fractions_m", "dp", &
    1766            3 :                "number_of_kpoints, max_number_of_states, number_of_spins, dos_fractions_m_lastsize"))
    1767            3 :    NCF_CHECK(ncerr)
    1768              :  end if
    1769              : 
    1770           28 :  if (allocated(dos%fractions_paw1)) then
    1771              :    ncerr = nctk_def_arrays(ncid, [&
    1772              :      nctkarr_t("dos_fractions_paw1", "dp", "number_of_kpoints, max_number_of_states, number_of_spins, ndosfraction"), &
    1773              :      nctkarr_t("dos_fractions_pawt1", "dp", "number_of_kpoints, max_number_of_states, number_of_spins, ndosfraction") &
    1774           24 :    ])
    1775            8 :    NCF_CHECK(ncerr)
    1776              :  end if
    1777              : 
    1778           28 :  if (dtset%natsph_extra /= 0) then
    1779              :    ncerr = nctk_def_arrays(ncid, [&
    1780              :      nctkarr_t("xredsph_extra", "dp", "number_of_reduced_dimensions, natsph_extra") &
    1781            2 :    ])
    1782            1 :    NCF_CHECK(ncerr)
    1783              :  end if
    1784              : 
    1785              :  ! Write variables
    1786           28 :  NCF_CHECK(nctk_set_datamode(ncid))
    1787              : 
    1788              :  ! scalars
    1789           28 :  NCF_CHECK(nf90_put_var(ncid, vid("pawprtdos"), dtset%pawprtdos))
    1790           28 :  NCF_CHECK(nf90_put_var(ncid, vid("prtdos"), dos%prtdos))
    1791           28 :  NCF_CHECK(nf90_put_var(ncid, vid("prtdosm"), dos%prtdosm))
    1792              : 
    1793              :  ! arrays
    1794           28 :  if (dtset%usepaw == 1) then
    1795           22 :    lmax_type = (pawtab(:)%l_size - 1) / 2
    1796              :  else
    1797           38 :    do itype=1,crystal%ntypat
    1798          121 :      lmax_type(itype) = maxval(psps%indlmn(1, :, itype))
    1799              :    end do
    1800              :  end if
    1801           28 :  NCF_CHECK(nf90_put_var(ncid, vid("lmax_type"), lmax_type))
    1802           28 :  NCF_CHECK(nf90_put_var(ncid, vid("dos_fractions"), dos%fractions))
    1803              : 
    1804           28 :  if (dos%prtdos == 3) then
    1805           20 :    NCF_CHECK(nf90_put_var(ncid, vid("iatsph"), dtset%iatsph(1:dtset%natsph)))
    1806           20 :    NCF_CHECK(nf90_put_var(ncid, vid("ratsph"), dtset%ratsph(1:dtset%ntypat)))
    1807           20 :    NCF_CHECK(nf90_put_var(ncid, vid("ratsph_extra"), dtset%ratsph_extra))
    1808           20 :    if (dtset%natsph_extra /= 0) then
    1809            1 :      NCF_CHECK(nf90_put_var(ncid, vid("xredsph_extra"), dtset%xredsph_extra(:, 1:dtset%natsph_extra)))
    1810              :    end if
    1811              :  end if
    1812              : 
    1813           28 :  if (allocated(dos%fractions_m)) then
    1814            3 :    NCF_CHECK(nf90_put_var(ncid, vid("dos_fractions_m"), dos%fractions_m))
    1815              :  end if
    1816           28 :  if (allocated(dos%fractions_paw1)) then
    1817            8 :    NCF_CHECK(nf90_put_var(ncid, vid("dos_fractions_paw1"), dos%fractions_paw1))
    1818            8 :    NCF_CHECK(nf90_put_var(ncid, vid("dos_fractions_pawt1"), dos%fractions_pawt1))
    1819              :  end if
    1820              : 
    1821           28 :  call cwtime(cpu,wall,gflops,"stop")
    1822           28 :  write(msg,'(2(a,f8.2),a)')" epjdos_ncwrite: cpu_time: ",cpu,"[s], walltime: ",wall," [s]"
    1823           28 :  call wrtout(std_out,msg,"PERS")
    1824              : 
    1825              : contains
    1826          220 :  integer function vid(vname)
    1827              :    character(len=*),intent(in) :: vname
    1828          220 :    vid = nctk_idname(ncid, vname)
    1829              :  end function vid
    1830              : 
    1831              : end subroutine epjdos_ncwrite
    1832              : !!***
    1833              : 
    1834              : !!****f* m_epjdos/partial_dos_fractions
    1835              : !! NAME
    1836              : !! partial_dos_fractions
    1837              : !!
    1838              : !! FUNCTION
    1839              : !! calculate partial DOS fractions to feed to the tetrahedron method
    1840              : !!  1: project states on angular momenta
    1841              : !!  2: should be able to choose certain atoms or atom types, slabs of space...
    1842              : !!
    1843              : !! INPUTS
    1844              : !!  crystal<crystal_t>= data type gathering info on symmetries and unit cell
    1845              : !!  dtset<type(dataset_type)>=all input variables for this dataset
    1846              : !!  npwarr(nkpt)=number of planewaves in basis at this k point
    1847              : !!  kg(3,mpw*mkmem)=reduced planewave coordinates.
    1848              : !!  cg(2,mcg)=planewave coefficients of wavefunctions
    1849              : !!  mcg=size of wave-functions array (cg) =mpw*my_nspinor*mband*mkmem*nsppol
    1850              : !!  collect=1 if fractions should be MPI collected at the end, 0 otherwise.
    1851              : !!  mpi_enreg=information about MPI parallelization
    1852              : !!
    1853              : !! SIDE EFFECTS
    1854              : !!  dos%fractions(ikpt,iband,isppol,ndosfraction) = percentage of s, p, d..
    1855              : !!    character on each atom for the wavefunction # ikpt,iband, isppol
    1856              : !!  == if prtdosm /= 0
    1857              : !!  dos%fractions_m(ikpt,iband,isppol,ndosfraction*mbesslang) = percentage of s, p, d..
    1858              : !!    character on each atom for the wavefunction # ikpt,iband, isppol (m-resolved)
    1859              : !!
    1860              : !! NOTES
    1861              : !!
    1862              : !!   psi(r) = (4pi/sqrt(ucvol)) \sum_{LMG} i**l u(G) e^{i(k+G).Ra} x Y_{LM}^*(k+G) Y_{LM}(r-Ra) j_L(|k+G||r-Ra|)
    1863              : !!
    1864              : !!   int_(ratsph) |psi(r)|**2 = \sum_LM rho(LM)
    1865              : !!
    1866              : !!   where
    1867              : !!
    1868              : !!   rho_{LM} = 4pi \int_o^{rc} dr r**2 ||\sum_G u(G) Y_LM^*(k+G) e^{i(k+G).Ra} j_L(|k+G| r)||**2
    1869              : !!
    1870              : !!   where S is a RSH. The final expression is:
    1871              : !!
    1872              : !!   When k = G0/2, we have u_{G0/2}(G) = u_{G0/2}(-G-G0)^* and P can be rewritten as
    1873              : !!
    1874              : !!     P = (4pi i^L}/sqrt(ucvol) \sum^'_G w(G) S_{LM}(k+G) \int_0^ratsph dr r^2 j_L(|k+G|r) x
    1875              : !!                                  2 Re[u_k(G) e^{i(k+G).R_atom}]  if L = 2n
    1876              : !!                                  2 Im[u_k(G) e^{i(k+G).R_atom}]  if L = 2n + 1
    1877              : !!
    1878              : !!  where the sum over G is done on the reduced G-sphere and w(G) = 1/2 if G=G0 else 1.
    1879              : !!
    1880              : !! SOURCE
    1881              : 
    1882           42 : subroutine partial_dos_fractions(dos,crystal,dtset,eigen,occ,npwarr,kg,cg,mcg,collect,mpi_enreg)
    1883              : 
    1884              : !Arguments ------------------------------------
    1885              : !scalars
    1886              :  class(epjdos_t),intent(inout) :: dos
    1887              :  integer,intent(in) :: mcg,collect
    1888              :  type(MPI_type),intent(inout) :: mpi_enreg
    1889              :  type(dataset_type),intent(in) :: dtset
    1890              :  type(crystal_t),intent(in) :: crystal
    1891              : !arrays
    1892              :  integer,intent(in) :: kg(3,dtset%mpw*dtset%mkmem),npwarr(dtset%nkpt)
    1893              :  real(dp),intent(in) :: cg(2,mcg)
    1894              :  real(dp),intent(in) :: eigen(dtset%mband*dtset%nkpt*dtset%nsppol)
    1895              :  real(dp),intent(in) :: occ(dtset%mband*dtset%nkpt*dtset%nsppol)
    1896              : 
    1897              : !Local variables-------------------------------
    1898              : !scalars
    1899              :  integer,parameter :: prtsphere0=0 ! do not output all the band by band details for projections.
    1900              :  integer :: shift_b,shift_sk,iat,iatom,iband,ierr,ikpt,ilang,ioffkg,is1, is2, isoff
    1901              :  integer :: ipw,isppol,ixint,mbess,mcg_disk,me_kpt,shift_cg
    1902              :  integer :: mgfft,my_nspinor,n1,n2,n3,natsph_tot,npw_k,nradintmax
    1903              :  integer :: rc_ylm,itypat,nband_k, abs_shift_b, unit_procar, ipauli
    1904              :  real(dp),parameter :: bessint_delta = 0.1_dp
    1905              :  real(dp) :: arg,bessarg,bessargmax,kpgmax,rmax, cpu,wall,gflops
    1906              :  character(len=500) :: msg
    1907              :  character(len=4) :: ikproc_str
    1908              :  character(len=fnlen) :: filename
    1909           42 :  type(jlspline_t) :: jlspl
    1910           42 :  type(MPI_type) :: mpi_enreg_seq
    1911              : !arrays
    1912           42 :  integer :: iindex(dtset%mpw),nband_tmp(1),npwarr_tmp(1)
    1913           42 :  integer,allocatable :: iatsph(:),nradint(:),atindx(:),typat_extra(:),kg_k(:,:)
    1914              :  real(dp) :: kpoint(3),spin(3),ylmgr_dum(1)
    1915           84 :  real(dp) :: xfit(dtset%mpw),yfit(dtset%mpw)
    1916           42 :  real(dp),allocatable :: ylm_k(:,:), bess_fit(:,:,:)
    1917           42 :  real(dp),allocatable :: cg_1band(:,:),cg_1kpt(:,:),kpgnorm(:),ph1d(:,:)
    1918           42 :  real(dp),allocatable :: ph3d(:,:,:),ratsph(:),rint(:),sum_1ll_1atom(:,:,:)
    1919           42 :  real(dp),allocatable :: sum_1lm_1atom(:,:,:), cplx_1lm_1atom(:,:,:,:)
    1920           42 :  real(dp),allocatable :: xred_sph(:,:),znucl_sph(:),phkxred(:,:)
    1921              :  complex(dp) :: cgcmat(2,2)
    1922              : !*************************************************************************
    1923              : 
    1924              : ! write(std_out, '(a)') ' m_epjdos%partial_dos_fractions : enter '
    1925              : 
    1926           42 :  if(dtset%natsph==dtset%natom)then
    1927           26 :    write(msg, '(a)') ' Compute the partial DOS fractions. This can be time-consuming. Think using natsph and iatsph.'
    1928              :  else
    1929           16 :    write(msg, '(a)') ' Compute the partial DOS fractions.'
    1930              :  endif
    1931           42 :  call wrtout(std_out,msg)
    1932              : 
    1933              :  ! for the moment, only support projection on angular momenta
    1934           42 :  if (dos%partial_dos_flag /= 1 .and. dos%partial_dos_flag /= 2) then
    1935            0 :    write(std_out,*) 'Error: partial_dos_fractions only supports angular '
    1936            0 :    write(std_out,*) ' momentum projection and spinor components for the moment. return to outscfcv'
    1937            0 :    write(std_out,*) ' partial_dos = ', dos%partial_dos_flag
    1938            0 :    return
    1939              :  end if
    1940              : 
    1941              :  ! impose all kpoints have same number of bands
    1942           89 :  do isppol=1,dtset%nsppol
    1943          443 :    do ikpt=1,dtset%nkpt
    1944          401 :      if (dtset%nband((isppol-1)*dtset%nkpt + ikpt) /= dtset%mband) then
    1945            0 :        write(std_out,*) 'Error: partial_dos_fractions wants same number of bands at each kpoint'
    1946            0 :        write(std_out,*) ' isppol, ikpt = ', isppol,ikpt, dtset%nband((isppol-1)*dtset%nkpt + ikpt), dtset%mband
    1947            0 :        write(std_out,*) ' all nband = ', dtset%nband
    1948            0 :        return
    1949              :      end if
    1950              :    end do
    1951              :  end do
    1952              : 
    1953              :  ! Real or complex spherical harmonics?
    1954           42 :  rc_ylm = 2; if (dos%prtdosm == 2) rc_ylm = 1
    1955              : 
    1956           42 :  me_kpt = mpi_enreg%me_kpt
    1957           42 :  my_nspinor = max(1,dtset%nspinor/mpi_enreg%nproc_spinor)
    1958              : 
    1959           42 :  n1 = dtset%ngfft(1); n2 = dtset%ngfft(2); n3 = dtset%ngfft(3)
    1960              :  mgfft = maxval(dtset%ngfft(1:3))
    1961              : 
    1962           42 :  call cwtime(cpu, wall, gflops, "start")
    1963              : 
    1964           42 :  if (dtset%prtprocar /= 0) then
    1965              :    ! open file for each proc, and print header for master node
    1966            1 :    call int2char4(me_kpt, ikproc_str)
    1967            1 :    filename = 'PROCAR_'//ikproc_str
    1968            1 :    if (open_file(filename, msg, newunit=unit_procar, form="formatted", action="write") /= 0) then
    1969            0 :       ABI_ERROR(msg)
    1970              :    end if
    1971            1 :    if(mpi_enreg%me==0) then
    1972            1 :      write (unit_procar,'(a)') 'PROCAR lm decomposed - need to merge files yourself in parallel case!!! Or use pyprocar package'
    1973            1 :      if (dtset%prtprocar == 2) then
    1974            1 :        write (unit_procar,'(a)') ' Requested complex output of PROCAR file (prtprocar 2)'
    1975              :      end if
    1976            1 :      write (unit_procar,'(a,I10,a,I10,a,I10,a)') '# of k-points: ', dtset%nkpt, &
    1977            2 :        ' # of bands:', dtset%mband, ' # of ions:', dtset%natom, ch10
    1978              :    end if
    1979              :  end if
    1980              : 
    1981              : !##############################################################
    1982              : !FIRST CASE: project on angular momenta to get dos parts
    1983              : !##############################################################
    1984              : 
    1985           42 :  if (dos%partial_dos_flag == 1) then
    1986           41 :    natsph_tot = dtset%natsph + dtset%natsph_extra
    1987              : 
    1988          123 :    ABI_MALLOC(iatsph, (natsph_tot))
    1989           82 :    ABI_MALLOC(typat_extra, (natsph_tot))
    1990          123 :    ABI_MALLOC(ratsph, (natsph_tot))
    1991           82 :    ABI_MALLOC(znucl_sph, (natsph_tot))
    1992           82 :    ABI_MALLOC(nradint, (natsph_tot))
    1993           82 :    ABI_MALLOC(atindx, (natsph_tot))
    1994          123 :    ABI_MALLOC(phkxred, (2,natsph_tot))
    1995              : 
    1996              :    ! initialize atindx
    1997          114 :    do iatom=1,natsph_tot
    1998          114 :      atindx(iatom) = iatom
    1999              :    end do
    2000              : 
    2001          102 :    iatsph(1:dtset%natsph) = dtset%iatsph(1:dtset%natsph)
    2002          102 :    do iatom=1,dtset%natsph
    2003           61 :      itypat = dtset%typat(iatsph(iatom))
    2004           61 :      typat_extra(iatom) = itypat
    2005           61 :      ratsph(iatom) = dtset%ratsph(itypat)
    2006          102 :      znucl_sph(iatom) = dtset%znucl(itypat)
    2007              :    end do
    2008              : 
    2009              :    ! fictitious atoms are declared with
    2010              :    ! %natsph_extra, %ratsph_extra and %xredsph_extra(3, dtset%natsph_extra)
    2011              :    ! they have atom index (natom + ii) and itype = ntypat + 1
    2012           53 :    do iatom=1,dtset%natsph_extra
    2013           12 :      typat_extra(iatom+dtset%natsph) = dtset%ntypat + 1
    2014           12 :      ratsph(iatom+dtset%natsph) = dtset%ratsph_extra
    2015           12 :      znucl_sph(iatom+dtset%natsph) = zero
    2016           53 :      iatsph(iatom+dtset%natsph) = dtset%natom + iatom
    2017              :    end do
    2018              : 
    2019              :    ! init bessel function integral for recip_ylm max ang mom + 1
    2020          205 :    ABI_MALLOC(sum_1ll_1atom,(dtset%nspinor**2,dos%mbesslang,natsph_tot))
    2021          205 :    ABI_MALLOC(sum_1lm_1atom,(dtset%nspinor**2,dos%mbesslang**2,natsph_tot))
    2022          205 :    ABI_MALLOC(cplx_1lm_1atom,(2,dtset%nspinor,dos%mbesslang**2,natsph_tot))
    2023              : 
    2024              :    ! Note ecuteff instead of ecut.
    2025           41 :    kpgmax = sqrt(dtset%ecut * dtset%dilatmx**2)
    2026           41 :    rmax = zero; bessargmax = zero; nradintmax = 0
    2027          114 :    do iatom=1,natsph_tot
    2028           73 :      rmax = max(rmax, ratsph(iatom))
    2029           73 :      bessarg = ratsph(iatom)*two_pi*kpgmax
    2030           73 :      bessargmax = max(bessargmax, bessarg)
    2031           73 :      nradint(iatom) = int (bessarg / bessint_delta) + 1
    2032          114 :      nradintmax = max(nradintmax,nradint(iatom))
    2033              :    end do
    2034              :    !write(std_out,*)' partial_dos_fractions: rmax=', rmax,' nradintmax: ", nradintmax
    2035              : !  use same number of grid points to calculate Bessel function and to do the integration later on r
    2036              : !  and make sure bessargmax is a multiple of bessint_delta
    2037           41 :    mbess = nradintmax
    2038           41 :    bessargmax = bessint_delta*mbess
    2039              : 
    2040          123 :    ABI_MALLOC(rint,(nradintmax))
    2041          205 :    ABI_MALLOC(bess_fit,(dtset%mpw,nradintmax,dos%mbesslang))
    2042              : 
    2043              :    ! initialize general Bessel function array on uniform grid xx, from 0 to (2 \pi |k+G|_{max} |r_{max}|)
    2044           41 :    call jlspl%init(mbess, bessint_delta, dos%mbesslang)
    2045              : 
    2046          123 :    ABI_MALLOC(xred_sph, (3, natsph_tot))
    2047          102 :    do iatom=1,dtset%natsph
    2048          285 :      xred_sph(:,iatom) = crystal%xred(:,iatsph(iatom))
    2049              :    end do
    2050           53 :    do iatom=1,dtset%natsph_extra
    2051           89 :      xred_sph(:,dtset%natsph+iatom) = dtset%xredsph_extra(:, iatom)
    2052              :    end do
    2053              : 
    2054          123 :    ABI_MALLOC(ph1d,(2,(2*n1+1 + 2*n2+1 + 2*n3+1)*natsph_tot))
    2055           41 :    call getph(atindx,natsph_tot,n1,n2,n3,ph1d,xred_sph)
    2056              : 
    2057              :    ! Fake MPI data to be used for sequential call to initylmg.
    2058           41 :    call initmpi_seq(mpi_enreg_seq)
    2059           41 :    mpi_enreg_seq%my_natom = dtset%natom
    2060              : 
    2061           41 :    shift_sk = 0
    2062           41 :    abs_shift_b =  0 ! offset to allow for automatic update with +1 below
    2063           87 :    do isppol=1,dtset%nsppol
    2064           46 :      ioffkg = 0
    2065              : 
    2066          431 :      do ikpt=1,dtset%nkpt
    2067          344 :        nband_k = dtset%nband((isppol-1)*dtset%nkpt + ikpt)
    2068          344 :        if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me_kpt)) then
    2069           78 :          abs_shift_b = abs_shift_b + nband_k ! jump the whole kpt in the eig and occ arrays
    2070           78 :          cycle
    2071              :        end if
    2072          266 :        npw_k = npwarr(ikpt)
    2073         1064 :        kpoint(:) = dtset%kpt(:,ikpt)
    2074              : 
    2075          266 :        if (dtset%prtprocar /= 0) then
    2076              :          write (unit_procar,'(a,I7,a,3F12.6,a,F12.6,a)') &
    2077            8 :            ' k-point ', ikpt, ' : ', kpoint(:), ' weight = ', dtset%wtk(ikpt), ch10
    2078              :        end if
    2079              : 
    2080              :        ! make phkred for all atoms
    2081          677 :        do iat=1,natsph_tot
    2082          411 :          arg=two_pi*( kpoint(1)*xred_sph(1,iat) + kpoint(2)*xred_sph(2,iat) + kpoint(3)*xred_sph(3,iat) )
    2083          411 :          phkxred(1,iat)=cos(arg)
    2084          677 :          phkxred(2,iat)=sin(arg)
    2085              :        end do
    2086              : 
    2087          798 :        ABI_MALLOC(kg_k, (3, npw_k))
    2088       210416 :        kg_k = kg(:,ioffkg+1:ioffkg+npw_k)
    2089              : 
    2090              :        ! kpgnorm contains norms only for kpoints used by this processor
    2091          798 :        ABI_MALLOC(kpgnorm, (npw_k))
    2092          266 :        call getkpgnorm(crystal%gprimd, kpoint, kg_k, kpgnorm, npw_k)
    2093              : 
    2094              :        ! Now get Ylm(k, G) factors: returns "real Ylms", which are real (+m) and
    2095              :        ! imaginary (-m) parts of actual complex Ylm. Yl-m = Ylm*
    2096              :        ! Call initylmg for a single k-point (mind mpi_enreg_seq).
    2097         1064 :        ABI_MALLOC(ylm_k, (npw_k, dos%mbesslang**2))
    2098          266 :        npwarr_tmp(1) = npw_k; nband_tmp(1) = nband_k
    2099              :        call initylmg(crystal%gprimd,kg_k,kpoint,1,mpi_enreg_seq,dos%mbesslang,&
    2100          266 :        npw_k,nband_tmp,1,npwarr_tmp,1,0,crystal%rprimd,ylm_k,ylmgr_dum)
    2101              : 
    2102              :        ! get phases exp (2 pi i (k+G).x_tau) in ph3d
    2103         1064 :        ABI_MALLOC(ph3d,(2,npw_k,natsph_tot))
    2104          266 :        call ph1d3d(1,natsph_tot,kg_k,natsph_tot,natsph_tot,npw_k,n1,n2,n3,phkxred,ph1d,ph3d)
    2105              : 
    2106              :        ! get Bessel function factors on array of |k+G|*r distances
    2107              :        ! since we need many r distances and have a large number of different
    2108              :        ! |k+G|, get j_l on uniform grid (above, in array gen_besj),
    2109              :        ! and spline it for each kpt Gvector set.
    2110              :        ! Note that we use the same step based on rmax, this can lead to (hopefully small)
    2111              :        ! inaccuracies when we integrate from 0 up to rmax(iatom)
    2112       113667 :        do ixint=1,nradintmax
    2113       113401 :          rint(ixint) = (ixint-1)*rmax / (nradintmax-1)
    2114     28972190 :          do ipw=1,npw_k
    2115     28858789 :            xfit(ipw) = two_pi * kpgnorm(ipw) * rint(ixint)
    2116     28972190 :            iindex(ipw) = ipw
    2117              :          end do
    2118              : 
    2119       113401 :          call sort_dp(npw_k,xfit,iindex,tol14)
    2120       680672 :          do ilang=1,dos%mbesslang
    2121       567005 :            call splint(mbess, jlspl%xx, jlspl%bess_spl(:,ilang), jlspl%bess_spl_der(:,ilang), npw_k, xfit, yfit)
    2122              :            ! re-order results for different G vectors
    2123    144974351 :            do ipw=1,npw_k
    2124    144860950 :              bess_fit(iindex(ipw),ixint,ilang) = yfit(ipw)
    2125              :            end do
    2126              :          end do
    2127              :        end do ! ixint
    2128              : 
    2129          266 :        shift_b = 0
    2130         4510 :        do iband=1,nband_k
    2131         4244 :          abs_shift_b = abs_shift_b + 1
    2132         4244 :          if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,iband,iband,isppol,me_kpt)) cycle
    2133              :          !write(std_out,*)"in band:",iband
    2134              :          ! TODO: eventually import eig and occ down to here - a pain, but printing outside would imply saving a huge array in memory
    2135         4244 :          if (dtset%prtprocar /= 0) then
    2136          200 :            write (unit_procar,'(a,I7,a,F12.6,a,F12.6,a)') 'band ', iband, ' # energy ', &
    2137          400 :              eigen(abs_shift_b), ' # occ. ', occ(abs_shift_b), ch10
    2138              :          end if
    2139              : 
    2140              :          ! Select wavefunction in cg array
    2141         4244 :          shift_cg = shift_sk + shift_b
    2142              : 
    2143              :          call recip_ylm(bess_fit, cg(:,shift_cg+1:shift_cg+my_nspinor*npw_k), dtset%istwfk(ikpt),&
    2144              : &          mpi_enreg, nradint, nradintmax, dos%mbesslang , dtset%mpw, natsph_tot, typat_extra, dos%mlang_type,&
    2145              : &          npw_k, dtset%nspinor, ph3d, prtsphere0, rint, ratsph, rc_ylm, sum_1ll_1atom, sum_1lm_1atom, cplx_1lm_1atom,&
    2146         4244 : &          crystal%ucvol, ylm_k, znucl_sph)
    2147              :          ! on exit the sum_1atom_* have both spinors counted
    2148              : 
    2149              :          ! Accumulate
    2150        10625 :          do iatom=1,natsph_tot
    2151        42530 :            do ilang=1,dos%mbesslang
    2152              :              dos%fractions(ikpt,iband,isppol,dos%mbesslang*(iatom-1) + ilang) &
    2153              : &             = dos%fractions(ikpt,iband,isppol,dos%mbesslang*(iatom-1) + ilang) &
    2154        38286 : &             + sum_1ll_1atom(1,ilang,iatom)
    2155              :            end do
    2156              :          end do
    2157              : 
    2158         4244 :          if (dos%prtdosm /= 0) then
    2159          409 :            do iatom=1,natsph_tot
    2160         5559 :              do ilang=1,dos%mbesslang**2
    2161              :                dos%fractions_m(ikpt,iband,isppol,dos%mbesslang**2*(iatom-1) + ilang) &
    2162              : &               = dos%fractions_m(ikpt,iband,isppol,dos%mbesslang**2*(iatom-1) + ilang) &
    2163         5356 : &               + sum_1lm_1atom(1,ilang,iatom)
    2164              :              end do
    2165              :            end do
    2166              :          end if
    2167              : 
    2168              :          ! Increment band, spinor shift
    2169              :          !shift_b = shift_b + npw_k
    2170         4244 :          shift_b = shift_b + my_nspinor*npw_k
    2171              : 
    2172              :          ! now we have both spinor components. The first option is for real values projections, eventually decomposed by Pauli spinor components
    2173         4510 :          if (dtset%prtprocar /= 0) then
    2174          200 :            write (unit_procar,'(a)') 'ion       s      py     pz     px    dxy    dyz    dz2    dxz    dx2    tot'
    2175          400 :            do ipauli= 1,dtset%nspinor**2
    2176              :              ! Contract with Pauli matrices to get projections for this k and band, all atoms and ilang
    2177          400 :              do iatom = 1, natsph_tot
    2178          200 :                write (unit_procar, '(1x,I5)', advance='no') iatom
    2179         2000 :                do ilang=1,min(dos%mbesslang**2,9)
    2180         2000 :                  write (unit_procar, '(F7.3)',advance='no') sum_1lm_1atom(ipauli,ilang,iatom)
    2181              :                end do
    2182         5400 :                write (unit_procar, '(F7.3)',advance='yes') sum(sum_1lm_1atom(ipauli,:,iatom))
    2183              :              end do
    2184              :              ! final line with sum over atoms
    2185          200 :              write (unit_procar, '(a)', advance='no') 'tot   '
    2186         2000 :              do ilang=1,min(dos%mbesslang**2,9)
    2187         3800 :                write (unit_procar, '(F7.3)',advance='no') sum(sum_1lm_1atom(ipauli,ilang,:))
    2188              :              end do
    2189         5600 :              write (unit_procar, '(F7.3)',advance='yes') sum(sum_1lm_1atom(ipauli,:,:))
    2190              :            end do
    2191              : 
    2192              :            ! second option is to also print the complex projection on the atomic like orbital: <psi_nk | Y_lm> in a sphere
    2193              :            !  Two blocks are printed, first real then imaginary part
    2194          200 :            if (dtset%prtprocar == 2) then
    2195          200 :              write (unit_procar,'(2a)') 'ion            s              py              pz              px',&
    2196          400 : &              '             dxy             dyz             dz2             dxz             dx2             tot'
    2197          400 :              do is1= 1,dtset%nspinor
    2198              :                ! Contracted with Pauli matrices to get projections for this k and band, all atoms and ilang
    2199          400 :                do iatom = 1, natsph_tot
    2200          200 :                  write (unit_procar, '(1x,I5)', advance='no') iatom
    2201         2000 :                  do ilang=1,min(dos%mbesslang**2,9)
    2202         2000 :                    write (unit_procar, '(2(F7.3,1x))',advance='no') cplx_1lm_1atom(:,is1,ilang,iatom)
    2203              :                  end do
    2204         5200 :                  write (unit_procar, '(2(F7.3,1x))',advance='yes') sum(cplx_1lm_1atom(1,is1,:,iatom)), &
    2205         5600 : &                   sum(cplx_1lm_1atom(2,is1,:,iatom))
    2206              :                end do
    2207              :                ! final line with sum over atoms
    2208          200 :                write (unit_procar, '(a)', advance='no') 'charge'
    2209         2000 :                do ilang=1,min(dos%mbesslang**2,9)
    2210         7400 :                  write (unit_procar, '(F7.3,9x)',advance='no') sum(cplx_1lm_1atom(:,is1,ilang,:)**2)
    2211              :                end do
    2212        15600 :                write (unit_procar, '(F7.3,9x)',advance='yes') sum(cplx_1lm_1atom(:,is1,:,:)**2)
    2213              :              end do
    2214          200 :              write (unit_procar,*)
    2215              :            end if
    2216              :          end if
    2217              : 
    2218              :        end do ! band
    2219              : 
    2220              :        ! Increment kpt and (spin, kpt) shifts
    2221          266 :        ioffkg = ioffkg + npw_k
    2222          266 :        shift_sk = shift_sk + nband_k*my_nspinor*npw_k
    2223              : 
    2224          266 :        ABI_FREE(kg_k)
    2225          266 :        ABI_FREE(kpgnorm)
    2226          266 :        ABI_FREE(ylm_k)
    2227          312 :        ABI_FREE(ph3d)
    2228              :      end do ! ikpt
    2229              :    end do ! isppol
    2230              : 
    2231              :    ! collect = 1 ==> gather all contributions from different processors
    2232           41 :    if (collect == 1) then
    2233           41 :      call xmpi_sum(dos%fractions,mpi_enreg%comm_kpt,ierr)
    2234           41 :      if (dos%prtdosm /= 0) call xmpi_sum(dos%fractions_m,mpi_enreg%comm_kpt,ierr)
    2235              : 
    2236              : ! this is now done inside recip_ylm
    2237              : !     if (mpi_enreg%paral_spinor == 1)then
    2238              : !       call xmpi_sum(dos%fractions,mpi_enreg%comm_spinor,ierr)
    2239              : !       if (dos%prtdosm /= 0) call xmpi_sum(dos%fractions_m,mpi_enreg%comm_spinor,ierr)
    2240              : !     end if
    2241              :    end if
    2242              : 
    2243           41 :    ABI_FREE(atindx)
    2244           41 :    ABI_FREE(bess_fit)
    2245           41 :    ABI_FREE(iatsph)
    2246           41 :    ABI_FREE(typat_extra)
    2247           41 :    ABI_FREE(nradint)
    2248           41 :    ABI_FREE(ph1d)
    2249           41 :    ABI_FREE(phkxred)
    2250           41 :    ABI_FREE(ratsph)
    2251           41 :    ABI_FREE(rint)
    2252           41 :    ABI_FREE(sum_1ll_1atom)
    2253           41 :    ABI_FREE(sum_1lm_1atom)
    2254           41 :    ABI_FREE(cplx_1lm_1atom)
    2255           41 :    ABI_FREE(xred_sph)
    2256           41 :    ABI_FREE(znucl_sph)
    2257              : 
    2258           41 :    call jlspl%free()
    2259           41 :    call destroy_mpi_enreg(mpi_enreg_seq)
    2260              : 
    2261              :  !##############################################################
    2262              :  !2ND CASE: project on spinors
    2263              :  !##############################################################
    2264              : 
    2265            1 :  else if (dos%partial_dos_flag == 2) then
    2266              : 
    2267            1 :    if (dtset%nsppol /= 1 .or. dtset%nspinor /= 2) then
    2268            0 :      ABI_WARNING("spinor projection is meaningless if nsppol==2 or nspinor/=2. Not calculating projections.")
    2269            0 :      return
    2270              :    end if
    2271            1 :    if (my_nspinor /= 2) then
    2272            0 :      ABI_WARNING("spinor projection with spinor parallelization is not coded. Not calculating projections.")
    2273            0 :      return
    2274              :    end if
    2275            1 :    ABI_CHECK(mpi_enreg%paral_spinor == 0, "prtdos 5 does not support spinor parallelism")
    2276              : 
    2277              :    ! FIXME: We should not allocate such a large chunk of memory!
    2278            1 :    mcg_disk = dtset%mpw*my_nspinor*dtset%mband
    2279            3 :    ABI_MALLOC(cg_1kpt,(2,mcg_disk))
    2280            1 :    shift_sk = 0
    2281            1 :    isppol = 1
    2282              : 
    2283           11 :    do ikpt=1,dtset%nkpt
    2284           10 :      nband_k = dtset%nband((isppol-1)*dtset%nkpt + ikpt)
    2285           10 :      if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me_kpt)) cycle
    2286           10 :      npw_k = npwarr(ikpt)
    2287              : 
    2288       793810 :      cg_1kpt(:,:) = cg(:,shift_sk+1:shift_sk+mcg_disk)
    2289           30 :      ABI_MALLOC(cg_1band,(2,2*npw_k))
    2290           10 :      shift_b=0
    2291          310 :      do iband=1,nband_k
    2292          300 :        if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,iband,iband,isppol,me_kpt)) cycle
    2293              : 
    2294              :        ! Select wavefunction in cg array
    2295              :        !shift_cg = shift_sk + shift_b
    2296       780960 :        cg_1band(:,:) = cg_1kpt(:,shift_b+1:shift_b+2*npw_k)
    2297          300 :        call cg_getspin(cg_1band, npw_k, spin, cgcmat=cgcmat)
    2298              : 
    2299              :        ! MG: TODO: imag part of off-diagonal terms is missing.
    2300              :        ! I will add them later on.
    2301          900 :        do is1=1,2
    2302         2100 :          do is2=1,2
    2303         1200 :            isoff = is2 + (is1-1)*2
    2304              :            dos%fractions(ikpt,iband,isppol,isoff) = dos%fractions(ikpt,iband,isppol,isoff) &
    2305         1800 : &           + real(cgcmat(is1,is2))
    2306              :          end do
    2307              :        end do
    2308              : 
    2309          300 :        dos%fractions(ikpt,iband,isppol,5) = dos%fractions(ikpt,iband,isppol,5) + spin(1)
    2310          300 :        dos%fractions(ikpt,iband,isppol,6) = dos%fractions(ikpt,iband,isppol,6) + spin(2)
    2311          300 :        dos%fractions(ikpt,iband,isppol,7) = dos%fractions(ikpt,iband,isppol,7) + spin(3)
    2312              : 
    2313          310 :        shift_b = shift_b + 2*npw_k
    2314              :      end do
    2315           10 :      ABI_FREE(cg_1band)
    2316           11 :      shift_sk = shift_sk + nband_k*2*npw_k
    2317              :    end do
    2318            1 :    ABI_FREE(cg_1kpt)
    2319              : 
    2320              :    ! Gather all contributions from different processors
    2321            1 :    if (collect == 1) then
    2322            1 :      call xmpi_sum(dos%fractions,mpi_enreg%comm_kpt,ierr)
    2323            1 :      call xmpi_sum(dos%fractions,mpi_enreg%comm_bandfft,ierr)
    2324              :      !below for future use - spinors should not be parallelized for the moment
    2325              :      !if (mpi_enreg%paral_spinor == 1)then
    2326              :      !  call xmpi_sum(dos%fractions,mpi_enreg%comm_spinor,ierr)
    2327              :      !end if
    2328              :    end if
    2329              : 
    2330              :  else
    2331            0 :    ABI_WARNING('only partial_dos==1 or 2 is coded')
    2332              :  end if
    2333              : 
    2334           42 :  if (dtset%prtprocar /= 0) close(unit_procar)
    2335              : 
    2336           42 :  call cwtime(cpu,wall,gflops,"stop")
    2337           42 :  write(msg,'(2(a,f8.2),a)')" partial_dos_fractions: cpu_time: ",cpu,"[s], walltime: ",wall," [s]"
    2338           42 :  call wrtout(std_out,msg,"PERS")
    2339              :  !write(std_out,*) ' m_epjdos%partial_dos_fractions : exit '
    2340              : 
    2341           42 : end subroutine partial_dos_fractions
    2342              : !!***
    2343              : 
    2344              : !!****f* m_epjdos/partial_dos_fractions_paw
    2345              : !! NAME
    2346              : !! partial_dos_fractions_paw
    2347              : !!
    2348              : !! FUNCTION
    2349              : !!  Calculate PAW contributions to the partial DOS fractions (tetrahedron method)
    2350              : !!
    2351              : !! INPUTS
    2352              : !!  cprj(natom,mcprj)= <p_lmn|Cnk> coefficients for each WF |Cnk> and each |p_lmn> non-local projector
    2353              : !!  dimcprj(natom)=array of dimensions of array cprj (not ordered)
    2354              : !!  dtset     structured datatype, from which one uses :
    2355              : !!   iatsph(nasph)=number of atoms used to project dos
    2356              : !!   kpt(3,nkpt)  =irreducible kpoints
    2357              : !!   mband        =max number of bands per k-point
    2358              : !!   mkmem        =number of kpoints in memory
    2359              : !!   natom        =number of atoms in total
    2360              : !!   natsph       =number of atoms ofor which the spherical decomposition must be done
    2361              : !!   nband        =number of electronic bands for each kpoint
    2362              : !!   nkpt         =number of irreducible kpoints
    2363              : !!   nspinor      =number of spinor components
    2364              : !!   nsppol       =1 or 2 spin polarization channels
    2365              : !!  fatbands_flag =1 if pawfatbnd=1 or 2
    2366              : !!  mbesslang=maximum angular momentum for Bessel function expansion
    2367              : !!  mpi_enreg=information about MPI parallelization
    2368              : !!  prtdosm=option for the m-contributions to the partial DOS
    2369              : !!  ndosfraction=natsph*mbesslang
    2370              : !!  paw_dos_flag=option for the PAW contributions to the partial DOS
    2371              : !!  pawrad(ntypat) <type(pawrad_type)>=paw radial mesh and related data:
    2372              : !!  pawtab(ntypat) <type(pawtab_type)>=paw tabulated starting data
    2373              : !!
    2374              : !! OUTPUT
    2375              : !!  === If paw_dos_flag==1:
    2376              : !!   dos%fractions_paw1(ikpt,iband,isppol,natom*mbesslang) = contribution to
    2377              : !!       dos fractions from the PAW partial waves (phi)
    2378              : !!   dos%fractions_pawt1(ikpt,iband,isppol,natom*mbesslang) = contribution to
    2379              : !!       dos fractions from the PAW pseudo partial waves (phi_tild)
    2380              : !!
    2381              : !! SIDE EFFECTS
    2382              : !!  dos%fractions(ikpt,iband,isppol,ndosfraction) = percentage of s, p, d..
    2383              : !!    character on each atom for the wavefunction # ikpt,iband, isppol
    2384              : !!    As input: contains only the pseudo contribution
    2385              : !!    As output: contains pseudo contribution + PAW corrections
    2386              : !!  == if prtdosm==1
    2387              : !!  dos%fractions_m(ikpt,iband,isppol,ndosfraction*mbesslang*prtdosm) =
    2388              : !!              m discretization of partial DOS fractions
    2389              : !!
    2390              : !! SOURCE
    2391              : 
    2392           24 : subroutine partial_dos_fractions_paw(dos,cprj,dimcprj,dtset,mcprj,mkmem,mpi_enreg,pawrad,pawtab)
    2393              : 
    2394              : !Arguments ------------------------------------
    2395              : !scalars
    2396              :  class(epjdos_t),intent(inout) :: dos
    2397              :  integer,intent(in) :: mcprj,mkmem
    2398              :  type(MPI_type),intent(in) :: mpi_enreg
    2399              :  type(dataset_type),intent(in) :: dtset
    2400              : !arrays
    2401              :  integer,intent(in) :: dimcprj(dtset%natom)
    2402              :  type(pawcprj_type),intent(in) :: cprj(dtset%natom,mcprj)
    2403              :  type(pawrad_type),intent(in) :: pawrad(dtset%ntypat)
    2404              :  type(pawtab_type),target,intent(in) :: pawtab(dtset%ntypat)
    2405              : 
    2406              : !Local variables-------------------------------
    2407              : !scalars
    2408              :  integer :: bandpp,basis_size,comm_kptband,cplex,fatbands_flag,iat,iatom,iband,ibg,ibsp
    2409              :  integer :: ierr,ikpt,il,ilang,ilmn,iln,im,iorder_cprj,ispinor,isppol,itypat,j0lmn,j0ln
    2410              :  integer :: jl,jlmn,jln,jm,klmn,kln,lmn_size,mbesslang,me_band,me_kpt,my_nspinor
    2411              :  integer :: nband_cprj_k,nband_k,ndosfraction,nprocband,nproc_spkptband,paw_dos_flag,prtdosm
    2412              :  real(dp) :: cpij,one_over_nproc
    2413              :  !character(len=500) :: msg
    2414              : !arrays
    2415           24 :  integer ,allocatable :: dimcprj_atsph(:)
    2416           24 :  integer,contiguous, pointer :: indlmn(:,:)
    2417              :  real(dp) :: tsec(2)
    2418           24 :  real(dp),allocatable :: int1(:,:),int2(:,:),int1m2(:,:)
    2419           24 :  type(pawcprj_type),allocatable :: cprj_k(:,:)
    2420              : !******************************************************************************************
    2421              : 
    2422              :  DBG_ENTER("COLL")
    2423              : 
    2424            0 :  ABI_CHECK(mkmem/=0,"mkmem==0 not supported anymore!")
    2425              : 
    2426           24 :  fatbands_flag = dos%fatbands_flag
    2427           24 :  mbesslang = dos%mbesslang
    2428           24 :  prtdosm = dos%prtdosm
    2429           24 :  ndosfraction = dos%ndosfraction
    2430           24 :  paw_dos_flag = dos%paw_dos_flag
    2431              : 
    2432              : !m-decomposed DOS not compatible with PAW-decomposed DOS
    2433           24 :  if(prtdosm>=1.and.paw_dos_flag==1) then
    2434            0 :    ABI_ERROR('m-decomposed DOS not compatible with PAW-decomposed DOS!')
    2435              :  end if
    2436              : 
    2437              : !Prepare some useful integrals
    2438           24 :  basis_size=pawtab(1)%basis_size
    2439           24 :  if (dtset%ntypat>1) then
    2440           30 :    do itypat=1,dtset%ntypat
    2441           30 :      basis_size=max(basis_size,pawtab(itypat)%basis_size)
    2442              :    end do
    2443              :  end if
    2444           96 :  ABI_MALLOC(int1  ,(basis_size*(basis_size+1)/2,dtset%natsph))
    2445           72 :  ABI_MALLOC(int2,(basis_size*(basis_size+1)/2,dtset%natsph))
    2446           72 :  ABI_MALLOC(int1m2,(basis_size*(basis_size+1)/2,dtset%natsph))
    2447         2181 :  int1=zero;int2=zero;int1m2=zero
    2448           62 :  do iat=1,dtset%natsph
    2449           38 :    iatom=dtset%iatsph(iat)
    2450           38 :    itypat= dtset%typat(iatom)
    2451          264 :    do jln=1,pawtab(itypat)%basis_size
    2452          202 :      j0ln=jln*(jln-1)/2
    2453          897 :      do iln=1,jln
    2454          657 :        kln=j0ln+iln
    2455          657 :        call simp_gen(int1(kln,iat),pawtab(itypat)%phiphj(:,kln),pawrad(itypat))
    2456          859 :        if (dtset%pawprtdos<2) then
    2457          549 :          call simp_gen(int2(kln,iat),pawtab(itypat)%tphitphj(:,kln),pawrad(itypat))
    2458          549 :          int1m2(kln,iat)=int1(kln,iat)-int2(kln,iat)
    2459              :        else
    2460          108 :          int2(kln,iat)=zero;int1m2(kln,iat)=int1(kln,iat)
    2461              :        end if
    2462              :      end do !iln
    2463              :    end do !jln
    2464              :  end do
    2465              : 
    2466              : !Antiferro case
    2467           24 :  if (dtset%nspden==2.and.dtset%nsppol==1.and.dtset%nspinor==1) then
    2468          178 :    int1m2(:,:)=half*int1m2(:,:)
    2469            2 :    if (paw_dos_flag==1.or.fatbands_flag==1.or.prtdosm==2) then
    2470          178 :      int1(:,:)=half*int1(:,:);int2(:,:)=half*int2(:,:)
    2471              :    end if
    2472              :  end if
    2473              : 
    2474              : !Init parallelism
    2475           24 :  comm_kptband=mpi_enreg%comm_kptband
    2476           24 :  nproc_spkptband=xmpi_comm_size(comm_kptband)*mpi_enreg%nproc_spinor
    2477           24 :  me_kpt=mpi_enreg%me_kpt ; me_band=mpi_enreg%me_band
    2478           24 :  my_nspinor=max(1,dtset%nspinor/mpi_enreg%nproc_spinor)
    2479           24 :  bandpp=1;if (mpi_enreg%paral_kgb==1) bandpp=mpi_enreg%bandpp
    2480              : !Check if cprj is distributed over bands
    2481           24 :  nprocband=my_nspinor*dtset%mband*dtset%mkmem*dtset%nsppol/mcprj
    2482           24 :  if (nprocband/=mpi_enreg%nproc_band) then
    2483            0 :    ABI_BUG('wrong mcprj/nproc_band!')
    2484              :  end if
    2485              : 
    2486              : !Quick hack: in case of parallelism, dos_fractions have already
    2487              : !  been reduced over MPI processes; they have to be prepared before
    2488              : !  the next reduction (at the end of the following loop).
    2489           24 :  if (nproc_spkptband>1) then
    2490           16 :    one_over_nproc=one/real(nproc_spkptband,kind=dp)
    2491              : !$OMP  PARALLEL DO COLLAPSE(4) DEFAULT(SHARED) PRIVATE(ilang,isppol,iband,ikpt)
    2492          136 :    do ilang=1,ndosfraction
    2493          256 :      do isppol=1,dtset%nsppol
    2494         4720 :        do iband=1,dtset%mband
    2495        25400 :          do ikpt=1,dtset%nkpt
    2496              :            dos%fractions(ikpt,iband,isppol,ilang)= &
    2497        25280 : &           one_over_nproc*dos%fractions(ikpt,iband,isppol,ilang)
    2498              :          end do
    2499              :        end do
    2500              :      end do
    2501              :    end do
    2502              : !$OMP END PARALLEL DO
    2503              : 
    2504           16 :    if (fatbands_flag==1.or.prtdosm==1.or.prtdosm==2) then
    2505              : !$OMP  PARALLEL DO COLLAPSE(4) DEFAULT(SHARED) PRIVATE(ilang,isppol,iband,ikpt)
    2506            0 :      do ilang=1,ndosfraction*mbesslang
    2507           16 :        do isppol=1,dtset%nsppol
    2508            0 :          do iband=1,dtset%mband
    2509            0 :            do ikpt=1,dtset%nkpt
    2510              :              dos%fractions_m(ikpt,iband,isppol,ilang)= &
    2511            0 : &             one_over_nproc*dos%fractions_m(ikpt,iband,isppol,ilang)
    2512              :            end do
    2513              :          end do
    2514              :        end do
    2515              :      end do
    2516              : !$OMP END PARALLEL DO
    2517              :    end if
    2518              :  end if
    2519              : 
    2520           24 :  iorder_cprj=0
    2521              : 
    2522              : !LOOPS OVER SPINS,KPTS
    2523           24 :  ibg=0
    2524           50 :  do isppol =1,dtset%nsppol
    2525          241 :    do ikpt=1,dtset%nkpt
    2526              : 
    2527          191 :      nband_k=dtset%nband(ikpt+(isppol-1)*dtset%nkpt)
    2528          191 :      if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,1,nband_k,isppol,me_kpt)) cycle
    2529              : 
    2530          133 :      cplex=2;if (dtset%istwfk(ikpt)>1) cplex=1
    2531          133 :      nband_cprj_k=nband_k/nprocband
    2532        10742 :      ABI_MALLOC(cprj_k,(dtset%natsph,my_nspinor*nband_cprj_k))
    2533          399 :      ABI_MALLOC(dimcprj_atsph,(dtset%natsph))
    2534          347 :      do iat=1,dtset%natsph
    2535          347 :        dimcprj_atsph(iat)=dimcprj(dtset%iatsph(iat))
    2536              :      end do
    2537          133 :      call pawcprj_alloc(cprj_k,0,dimcprj_atsph)
    2538          133 :      ABI_FREE(dimcprj_atsph)
    2539              : 
    2540              : !    Extract cprj for this k-point.
    2541          133 :      ibsp=0
    2542         3183 :      do iband=1,nband_cprj_k
    2543         6633 :        do ispinor=1,my_nspinor
    2544         3450 :          ibsp=ibsp+1
    2545        13260 :          do iat=1,dtset%natsph
    2546         6760 :            iatom=dtset%iatsph(iat)
    2547       343030 :            cprj_k(iat,ibsp)%cp(:,:)=cprj(iatom,ibsp+ibg)%cp(:,:)
    2548              :          end do
    2549              :        end do
    2550              :      end do
    2551              : 
    2552              : !    LOOP OVER ATOMS (natsph_extra is not included on purpose)
    2553          347 :      do iat=1,dtset%natsph
    2554          214 :        iatom=dtset%iatsph(iat)
    2555          214 :        itypat= dtset%typat(iatom)
    2556          214 :        lmn_size=pawtab(itypat)%lmn_size
    2557          214 :        indlmn => pawtab(itypat)%indlmn
    2558              : 
    2559              : !      LOOP OVER BANDS
    2560          214 :        ibsp=0
    2561         6307 :        do iband=1,nband_k
    2562              : 
    2563         5960 :          if (mod((iband-1)/bandpp,nprocband)/=me_band) cycle
    2564         5960 :          if (proc_distrb_cycle(mpi_enreg%proc_distrb,ikpt,iband,iband,isppol,me_kpt)) then
    2565            0 :            ibsp=ibsp+my_nspinor;cycle
    2566              :          end if
    2567              : 
    2568        12934 :          do ispinor=1,my_nspinor
    2569         6760 :            ibsp=ibsp+1
    2570              : 
    2571        46520 :            do ilang=1,mbesslang
    2572              : 
    2573       595260 :              do jlmn=1,lmn_size
    2574       554700 :                jl=indlmn(1,jlmn)
    2575       554700 :                jm=indlmn(2,jlmn)
    2576       554700 :                j0lmn=jlmn*(jlmn-1)/2
    2577      5773700 :                do ilmn=1,jlmn
    2578      5185200 :                  il=indlmn(1,ilmn)
    2579      5185200 :                  im=indlmn(2,ilmn)
    2580      5185200 :                  klmn=j0lmn+ilmn
    2581      5185200 :                  kln=pawtab(itypat)%indklmn(2,klmn)
    2582              : 
    2583      5739900 :                  if (il==ilang-1.and.jl==ilang-1.and.im==jm) then
    2584              : 
    2585       163560 :                    cpij=cprj_k(iat,ibsp)%cp(1,ilmn)*cprj_k(iat,ibsp)%cp(1,jlmn)
    2586       163560 :                    if (cplex==2) cpij=cpij+cprj_k(iat,ibsp)%cp(2,ilmn)*cprj_k(iat,ibsp)%cp(2,jlmn)
    2587       163560 :                    cpij=pawtab(itypat)%dltij(klmn)*cpij
    2588              : 
    2589              :                    dos%fractions(ikpt,iband,isppol,mbesslang*(iat-1)+ilang)=  &
    2590              : &                   dos%fractions(ikpt,iband,isppol,mbesslang*(iat-1)+ilang) + &
    2591       163560 : &                   cpij*int1m2(kln,iat)
    2592       163560 :                    if (prtdosm==1) then
    2593              :                      dos%fractions_m(ikpt,iband,isppol,mbesslang**2*(iat-1)+il**2+il+1+im)= &
    2594              : &                     dos%fractions_m(ikpt,iband,isppol,mbesslang**2*(iat-1)+il**2+il+1+im) + &
    2595         5400 : &                     cpij*int1m2(kln,iat)
    2596              :                    end if
    2597       163560 :                    if (fatbands_flag==1.or.prtdosm==2) then
    2598              :                      dos%fractions_m(ikpt,iband,isppol,mbesslang**2*(iat-1)+il**2+il+1+im)= &
    2599              : &                     dos%fractions_m(ikpt,iband,isppol,mbesslang**2*(iat-1)+il**2+il+1+im) + &
    2600        42240 : &                     cpij*int1(kln,iat)
    2601              :                    end if
    2602       163560 :                    if (paw_dos_flag==1) then
    2603              :                      dos%fractions_paw1(ikpt,iband,isppol,mbesslang*(iat-1)+ilang)=  &
    2604              : &                     dos%fractions_paw1(ikpt,iband,isppol,mbesslang*(iat-1)+ilang) + &
    2605            0 : &                     cpij*int1(kln,iat)
    2606              :                      dos%fractions_pawt1(ikpt,iband,isppol,mbesslang*(iat-1)+ilang)=  &
    2607              : &                     dos%fractions_pawt1(ikpt,iband,isppol,mbesslang*(iat-1)+ilang) + &
    2608            0 : &                     cpij*int2(kln,iat)
    2609              :                    end if
    2610              : 
    2611              :                  end if
    2612              : 
    2613              :                end do !ilmn
    2614              :              end do   !jlmn
    2615              : 
    2616              :            end do ! ilang
    2617              :          end do ! ispinor
    2618              :        end do ! iband
    2619              : 
    2620              :      end do !iatom
    2621              : 
    2622          133 :      if (mkmem/=0) ibg = ibg + my_nspinor*nband_cprj_k
    2623          133 :      call pawcprj_free(cprj_k)
    2624         6977 :      ABI_FREE(cprj_k)
    2625              :    end do ! ikpt
    2626              :  end do ! isppol
    2627              : 
    2628           24 :  ABI_FREE(int1)
    2629           24 :  ABI_FREE(int2)
    2630           24 :  ABI_FREE(int1m2)
    2631              : 
    2632              : !Reduce data in case of parallelism
    2633           24 :  call timab(48,1,tsec)
    2634           24 :  call xmpi_sum(dos%fractions,comm_kptband,ierr)
    2635           24 :  if (prtdosm>=1.or.fatbands_flag==1) then
    2636            2 :    call xmpi_sum(dos%fractions_m,comm_kptband,ierr)
    2637              :  end if
    2638           24 :  if (paw_dos_flag==1) then
    2639            0 :    call xmpi_sum(dos%fractions_paw1,comm_kptband,ierr)
    2640            0 :    call xmpi_sum(dos%fractions_pawt1,comm_kptband,ierr)
    2641              :  end if
    2642           24 :  call timab(48,2,tsec)
    2643           24 :  if (mpi_enreg%paral_spinor==1) then
    2644            4 :    call xmpi_sum(dos%fractions,mpi_enreg%comm_spinor,ierr)
    2645            4 :    if (prtdosm>=1.or.fatbands_flag==1) then
    2646            0 :      call xmpi_sum(dos%fractions_m,mpi_enreg%comm_spinor,ierr)
    2647              :    end if
    2648            4 :    if (paw_dos_flag==1) then
    2649            0 :      call xmpi_sum(dos%fractions_paw1, mpi_enreg%comm_spinor,ierr)
    2650            0 :      call xmpi_sum(dos%fractions_pawt1, mpi_enreg%comm_spinor,ierr)
    2651              :    end if
    2652              :  end if
    2653              : 
    2654              : !Averaging: A quick hack for m-decomposed LDOS:
    2655              : !BA: not valid in presence of spin-orbit coupling  !
    2656           24 :  if (prtdosm==1.and.fatbands_flag==0) then
    2657              : !  if pawfatbnd is activated, one think in the cubic harmonics basis
    2658              : !  whereas prtdosm=1 is in the spherical harmonics basis.
    2659              : !  the following trick is done in order to have everything
    2660              : !  in the complex spherical basis (not useful for pawfatbnd if we want to
    2661              : !  have e.g t2g and eg d-orbitals).
    2662            2 :    do iat=1,dtset%natsph
    2663            7 :      do il = 0, mbesslang-1
    2664           16 :        do im = 1, il
    2665              :          dos%fractions_m(:,:,:,mbesslang**2*(iat-1)+il**2+il+1+im) = &
    2666              :            (dos%fractions_m(:,:,:,mbesslang**2*(iat-1)+il**2+il+1+im) + &
    2667         2530 :            dos%fractions_m(:,:,:,mbesslang**2*(iat-1)+il**2+il+1-im))/2
    2668              :          dos%fractions_m(:,:,:,mbesslang**2*(iat-1)+il**2+il+1-im) = &
    2669         2535 :            dos%fractions_m(:,:,:,mbesslang**2*(iat-1)+il**2+il+1+im)
    2670              :        end do
    2671              :      end do
    2672              :    end do !iatom
    2673              :  end if
    2674              : 
    2675              :  DBG_EXIT("COLL")
    2676              : 
    2677           72 : end subroutine partial_dos_fractions_paw
    2678              : !!***
    2679              : 
    2680            0 : end module m_epjdos
    2681              : !!***
        

Generated by: LCOV version 2.3-1