LCOV - code coverage report
Current view: top level - src/56_recipspace - m_skw.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 70.3 % 286 201
Test Date: 2026-11-10 16:57:26 Functions: 66.7 % 12 8
Branches: 41.6 % 830 345

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_skw
       2                 :             : !! NAME
       3                 :             : !!  m_skw
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!  Shankland-Koelling-Wood Fourier interpolation scheme.
       7                 :             : !!
       8                 :             : !! COPYRIGHT
       9                 :             : !! Copyright (C) 2008-2026 ABINIT group (MG)
      10                 :             : !! This file is distributed under the terms of the
      11                 :             : !! GNU General Public License, see ~abinit/COPYING
      12                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
      13                 :             : !!
      14                 :             : !! SOURCE
      15                 :             : 
      16                 :             : #if defined HAVE_CONFIG_H
      17                 :             : #include "config.h"
      18                 :             : #endif
      19                 :             : 
      20                 :             : #include "abi_common.h"
      21                 :             : 
      22                 :             : module m_skw
      23                 :             : 
      24                 :             :  use defs_basis
      25                 :             :  use m_errors
      26                 :             :  use m_abicore
      27                 :             :  use m_xmpi
      28                 :             :  use m_crystal
      29                 :             :  use m_sort
      30                 :             :  use m_nctk
      31                 :             :  use netcdf
      32                 :             : 
      33                 :             :  use m_fstrings,       only : itoa, sjoin, ktoa, yesno, ftoa
      34                 :             :  use m_special_funcs,  only : abi_derfc
      35                 :             :  use m_time,           only : cwtime, cwtime_report
      36                 :             :  use m_numeric_tools,  only : imax_loc
      37                 :             :  use m_bz_mesh,        only : isamek
      38                 :             :  use m_gsphere,        only : get_irredg
      39                 :             : 
      40                 :             :  implicit none
      41                 :             : 
      42                 :             :  private
      43                 :             : !!***
      44                 :             : 
      45                 :             : !----------------------------------------------------------------------
      46                 :             : 
      47                 :             : !!****t* m_skw/skw_t
      48                 :             : !! NAME
      49                 :             : !! skw_t
      50                 :             : !!
      51                 :             : !! FUNCTION
      52                 :             : !!  Object implementing the Shankland-Koelling-Wood Fourier interpolation scheme.
      53                 :             : !!  It can be used to interpolate functions in k-space with the periodicity of the
      54                 :             : !!  reciprocal lattice and satisfying F(k) = F(Sk) for each rotation S
      55                 :             : !!  belonging to the point group of the crystal. For readability reason,
      56                 :             : !!  the names of the variables are chosen assuming we are interpolating electronic eigenvalues
      57                 :             : !!  but the same object can be used to interpolate phonons as well. Just use nsppol=1 and nband = 3 * natom
      58                 :             : !!
      59                 :             : !! SOURCE
      60                 :             : 
      61                 :             :  type,public :: skw_t
      62                 :             : 
      63                 :             :   integer :: cplex
      64                 :             :    ! 1 if time-reversal symmetry can be used, 2 otherwise.
      65                 :             : 
      66                 :             :   integer :: nr
      67                 :             :    ! Number of star functions.
      68                 :             : 
      69                 :             :   integer :: nkpt
      70                 :             :    ! Number of ab-initio k-points.
      71                 :             : 
      72                 :             :   integer :: ptg_nsym
      73                 :             :    ! Number of operations in the point group.
      74                 :             : 
      75                 :             :   logical :: has_inversion
      76                 :             :    ! True if the point group contains spatial inversion.
      77                 :             : 
      78                 :             :   integer :: band_block(2)
      79                 :             :    ! Initial and final band index.
      80                 :             : 
      81                 :             :   integer :: bcount
      82                 :             :    ! Number of bands
      83                 :             : 
      84                 :             :   integer :: nsppol
      85                 :             :    ! Number of independent spin polarizations.
      86                 :             : 
      87                 :             :   integer,allocatable :: rpts(:,:)
      88                 :             :    ! rpts(3, nr)
      89                 :             :    ! Real-space lattice points (in reduced coordinates) ordered with non-decreasing length.
      90                 :             : 
      91                 :             :   integer,allocatable :: ptg_symrel(:,:,:)
      92                 :             :     ! ptg_symrel(3,3,ptg_nsym)
      93                 :             :     ! operations of the point group (real space).
      94                 :             : 
      95                 :             :   integer,allocatable :: ptg_symrec(:,:,:)
      96                 :             :     ! ptg_symrec(3,3,ptg_nsym)
      97                 :             :     ! operations of the point group (reciprocal space).
      98                 :             : 
      99                 :             :   complex(dp),allocatable :: coefs(:,:,:)
     100                 :             :    ! coefs(nr, bcount, nsppol).
     101                 :             : 
     102                 :             :   complex(dp),allocatable :: cached_srk(:)
     103                 :             :    ! cached_srk(%nr)
     104                 :             :    ! The star function for cached_kpt (used in skw_eval_bks).
     105                 :             :   real(dp) :: cached_kpt(3)
     106                 :             : 
     107                 :             :   complex(dp),allocatable :: cached_srk_dk1(:,:)
     108                 :             :    ! cached_srk_dk1(%nr, 3)
     109                 :             :    ! The 1d derivative wrt k of the star function for cached_kpt_dk1 (used in skw_eval_bks).
     110                 :             :   real(dp) :: cached_kpt_dk1(3)
     111                 :             : 
     112                 :             :   complex(dp),allocatable :: cached_srk_dk2(:,:,:)
     113                 :             :    ! cached_srk_dk2(%nr,3,3)
     114                 :             :    ! The 2d derivatives wrt k of the star function for cached_kpt_dk2 (used in skw_eval_bks).
     115                 :             :   real(dp) :: cached_kpt_dk2(3)
     116                 :             : 
     117                 :             :  contains
     118                 :             : 
     119                 :             :    procedure :: print => skw_print
     120                 :             :    ! Print info about object.
     121                 :             : 
     122                 :             :    procedure :: ncwrite => skw_ncwrite
     123                 :             :    ! Write the object in netcdf format
     124                 :             : 
     125                 :             :    procedure :: eval_bks => skw_eval_bks
     126                 :             :    ! Interpolate eigenvalues, 1st, 2nd derivates wrt k, at an arbitrary k-point.
     127                 :             : 
     128                 :             :    procedure :: free => skw_free
     129                 :             :    ! Free memory.
     130                 :             : 
     131                 :             :  end type skw_t
     132                 :             : !!***
     133                 :             : 
     134                 :             :  public :: skw_new          ! Create new object.
     135                 :             : 
     136                 :             : CONTAINS  !=====================================================================================
     137                 :             : !!***
     138                 :             : 
     139                 :             : !!****f* m_skw/skw_new
     140                 :             : !! NAME
     141                 :             : !!  skw_new
     142                 :             : !!
     143                 :             : !! FUNCTION
     144                 :             : !!  Initialize the object.
     145                 :             : !!
     146                 :             : !! INPUTS
     147                 :             : !!  cryst<crystal_t>=Crystalline structure.
     148                 :             : !!  params(:)
     149                 :             : !!     params(1): Ratio between star functions and ab-initio k-points.
     150                 :             : !!     params(2:3): Activate Fourier filtering (Eq 9 of PhysRevB.61.1639 [[cite:Uehara2000]]) if params(2) > tol6
     151                 :             : !!       params(2)=rcut, params(3) = rsigma
     152                 :             : !!  cplex=1 if time reversal can be used, 2 otherwise.
     153                 :             : !!  nband=Total Number of bands in the eig array.
     154                 :             : !!  nkpt=Number of ab-initio k-points.
     155                 :             : !!  nsppol=Number of independent spin polarizations.
     156                 :             : !!  kpts(3,nkpt)=ab-initio k-points in reduced coordinates.
     157                 :             : !!  eig(nband,nkpt,nsppol)=ab-initio eigenvalues.
     158                 :             : !!  band_block(2)=Initial and final band index to interpolate. If [0,0], all bands are used
     159                 :             : !!    This is a global variable i.e. all MPI procs MUST call the routine with the same value.
     160                 :             : !!  comm=MPI communicator
     161                 :             : !!
     162                 :             : !! SOURCE
     163                 :             : 
     164                 :          14 : type(skw_t) function skw_new(cryst, params, cplex, nband, nkpt, nsppol, kpts, eig, band_block, comm) result(new)
     165                 :             : 
     166                 :             : !Arguments ------------------------------------
     167                 :             : !scalars
     168                 :             :  integer,intent(in) :: cplex,nband,nkpt,nsppol,comm
     169                 :             :  real(dp),intent(in) :: params(:)
     170                 :             :  type(crystal_t),intent(in) :: cryst
     171                 :             : !arrays
     172                 :             :  integer,intent(in) :: band_block(2)
     173                 :             :  real(dp),intent(in) :: kpts(3,nkpt)
     174                 :             :  real(dp),intent(in) :: eig(nband,nkpt,nsppol)
     175                 :             : 
     176                 :             : !Local variables-------------------------------
     177                 :             : !scalars
     178                 :             :  integer,parameter :: master=0,prtvol=1
     179                 :             :  integer :: my_rank,nprocs,cnt,bstop,bstart,bcount,lwork
     180                 :             :  integer :: ir,ik,ib,ii,jj,nr,band,spin,ierr,lpratio,nrwant
     181                 :             :  real(dp),parameter :: c1=0.25_dp,c2=0.25_dp
     182                 :             :  real(dp) :: r2,r2min,mare,mae_meV,adiff_meV,rel_err,rcut,rsigma
     183                 :             :  real(dp) :: cpu_tot,wall_tot,gflops_tot,cpu,wall,gflops,rval
     184                 :             :  character(len=500) :: fmt,msg
     185                 :             : !arrays
     186                 :             :  integer :: rmax(3)
     187                 :           7 :  integer,allocatable :: ipiv(:)
     188                 :             :  real(dp) :: list2(2)
     189                 :           7 :  real(dp),allocatable :: r2vals(:),inv_rhor(:),oeig(:)
     190                 :           7 :  complex(dp),allocatable :: srk(:,:),hmat(:,:),lambda(:,:,:),work(:)
     191                 :             : ! *********************************************************************
     192                 :             : 
     193         [ -  + ]:           7 :  ABI_CHECK(nkpt > 1, sjoin("nkpt must be > 1 but got:", itoa(nkpt)))
     194                 :             : 
     195                 :           7 :  call cwtime(cpu_tot, wall_tot, gflops_tot, "start")
     196                 :             : 
     197                 :           7 :  nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
     198                 :             : 
     199                 :             :  ! Get slice of bands to be treated.
     200   [ +  +  +  -  :          21 :  new%band_block = band_block; if (all(band_block == 0)) new%band_block = [1, nband]
          -  +  -  +  -  
                      - ]
     201                 :           7 :  bstart = new%band_block(1); bstop = new%band_block(2); bcount = bstop - bstart + 1
     202                 :           7 :  new%cplex = cplex; new%nkpt = nkpt; new%nsppol = nsppol; new%bcount = bcount
     203                 :             : 
     204                 :             :  ! Get point group operations.
     205   [ -  +  -  + ]:           7 :  call cryst%get_point_group(new%ptg_nsym, new%ptg_symrel, new%ptg_symrec, new%has_inversion, include_timrev=cplex==1)
     206                 :             : 
     207                 :             :  ! -----------------------
     208                 :             :  ! Find nrwant star points
     209                 :             :  ! -----------------------
     210                 :           7 :  lpratio = int(abs(params(1)))
     211         [ -  + ]:           7 :  ABI_CHECK(lpratio > 0, "lpratio must be > 0")
     212         [ +  + ]:          28 :  rmax = nint((one + (lpratio * new%nkpt * new%ptg_nsym) / two) ** third)
     213         [ +  - ]:           7 :  if (new%has_inversion) then
     214         [ +  + ]:          28 :    rmax = nint((one + (lpratio * new%nkpt * new%ptg_nsym / 2) / two) ** third)
     215                 :             :  end if
     216                 :           7 :  nrwant = lpratio * new%nkpt
     217                 :             : 
     218                 :           7 :  call cwtime(cpu, wall, gflops, "start")
     219                 :           0 :  do
     220         [ -  + ]:           7 :    call find_rstar_gen(new, cryst, nrwant, rmax, r2vals, comm)
     221         [ -  + ]:           7 :    if (new%nr >= nrwant) then
     222                 :             :      !write(std_out,*)"Entered with rmax", rmax," abs(skw%rpts(last)): ", abs(new%rpts(:,new%nr))
     223                 :             :      exit
     224                 :             :    end if
     225                 :           0 :    write(std_out,*)"rmax: ", rmax," was not large enough to find ", nrwant," R-star points."
     226         [ #  # ]:           0 :    rmax = 2 * rmax
     227                 :           0 :    write(std_out,*)"Will try again with enlarged rmax: ",rmax
     228         [ #  # ]:           0 :    ABI_FREE(r2vals)
     229                 :             :  end do
     230                 :           7 :  nr = new%nr
     231                 :           7 :  call cwtime_report(" find_rstar_gen", cpu, wall, gflops)
     232                 :             : 
     233         [ +  - ]:           7 :  if (my_rank == master) call new%print(std_out)
     234                 :             : 
     235                 :             :  ! Compute (inverse) roughness function.
     236                 :           7 :  r2min = r2vals(2)
     237   [ -  +  +  -  :          21 :  ABI_MALLOC(inv_rhor, (nr))
          +  -  +  -  -  
                +  -  + ]
     238         [ +  + ]:         382 :  do ir=1,nr
     239                 :         375 :    r2 = r2vals(ir)
     240                 :         382 :    inv_rhor(ir) = one / ((one - c1 * r2/r2min)**2 + c2 * (r2 / r2min)**3)
     241                 :             :    ! TODO: Test the two versions.
     242                 :             :    !if (params(1) < zero) inv_rhor(ir) = one / (c1 * r2 + c2 * r2**2)
     243                 :             :  end do
     244                 :             : 
     245                 :             :  ! Construct star functions for the ab-initio k-points.
     246   [ -  +  +  -  :          28 :  ABI_MALLOC(srk, (nr, nkpt))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     247         [ +  + ]:          82 :  do ik=1,nkpt
     248                 :          82 :    call mkstar(new, kpts(:,ik), srk(:,ik))
     249                 :             :  end do
     250                 :             : 
     251                 :             :  ! Build H(k,k') matrix (Hermitian)
     252   [ +  -  -  +  :        1150 :  ABI_CALLOC(hmat, (nkpt-1, nkpt-1))
          +  -  -  +  +  
          -  +  -  +  -  
          -  +  -  +  +  
                +  +  + ]
     253                 :             :  cnt = 0
     254         [ +  + ]:          75 :  do jj=1,nkpt-1
     255         [ +  + ]:         636 :    do ii=1,jj
     256                 :             :    !do ii=1,nkpt-1
     257         [ +  - ]:         561 :      cnt = cnt + 1; if (mod(cnt, nprocs) /= my_rank) cycle ! mpi parallelism.
     258         [ +  + ]:       64988 :      do ir=2,nr
     259                 :             :        hmat(ii, jj) = hmat(ii, jj) + &
     260                 :       64920 :          (srk(ir, ii) - srk(ir, nkpt)) * conjg(srk(ir, jj) - srk(ir, nkpt)) * inv_rhor(ir)
     261                 :             :      end do
     262                 :             :    end do
     263                 :             :  end do
     264                 :           7 :  call xmpi_sum(hmat, comm, ierr)
     265                 :             : 
     266   [ -  +  +  -  :          35 :  ABI_MALLOC(lambda, (nkpt-1, bcount, nsppol))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                      + ]
     267         [ +  + ]:          14 :  do spin=1,nsppol
     268         [ +  + ]:          98 :    do ib=1,bcount
     269                 :          84 :      band = ib + bstart - 1
     270         [ +  + ]:         819 :      lambda(:,ib,spin) = eig(band,1:nkpt-1,spin) - eig(band,nkpt,spin)
     271                 :             :    end do
     272                 :             :  end do
     273                 :             : 
     274                 :             :  ! Solve all bands and spins at once [[cite:Pickett1988]]
     275                 :           7 :  call wrtout(std_out, " Solving system of linear equations to get lambda coeffients (eq. 10 of PRB 38 2721)...", do_flush=.True.)
     276                 :           7 :  call cwtime(cpu, wall, gflops, "start")
     277   [ -  +  +  -  :          21 :  ABI_MALLOC(ipiv, (nkpt-1))
          +  -  +  -  -  
                +  -  + ]
     278                 :             : 
     279                 :             :  if (.False.) then
     280                 :             :    ! General complex.
     281                 :             :    call zgesv(nkpt-1, bcount*nsppol, hmat, nkpt-1, ipiv, lambda, nkpt-1, ierr)
     282                 :             :    ABI_CHECK(ierr == 0, sjoin("ZGESV returned:", itoa(ierr)))
     283                 :             :  else
     284                 :             :    ! Hermitian version
     285         [ +  + ]:          75 :    do ii=1,nkpt-1
     286                 :          75 :      hmat(ii, ii) = real(hmat(ii, ii))
     287                 :             :    end do
     288                 :           7 :    lwork = -1
     289         [ -  + ]:           7 :    ABI_MALLOC(work, (1))
     290                 :           7 :    call zhesv("U", nkpt-1, bcount*nsppol, hmat, nkpt-1, ipiv, lambda, nkpt-1, work, lwork, ierr)
     291                 :           7 :    lwork = nint(real(work(1)))
     292                 :           7 :    ABI_FREE(work)
     293   [ -  +  +  -  :          21 :    ABI_MALLOC(work, (lwork))
          +  -  +  -  -  
                +  -  + ]
     294                 :           7 :    call zhesv("U", nkpt-1, bcount*nsppol, hmat, nkpt-1, ipiv, lambda, nkpt-1, work, lwork, ierr)
     295         [ -  + ]:           7 :    ABI_CHECK(ierr == 0, sjoin("ZHESV returned:", itoa(ierr)))
     296         [ -  + ]:           7 :    ABI_FREE(work)
     297                 :             :  end if
     298                 :           7 :  call cwtime_report(" ZHESV", cpu, wall, gflops)
     299                 :             : 
     300                 :             :  ! Compute coefficients
     301   [ -  +  +  -  :          35 :  ABI_MALLOC(new%coefs, (nr,bcount,nsppol))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
     302                 :             : 
     303         [ +  + ]:          14 :  do spin=1,nsppol
     304         [ +  + ]:          98 :    do ib=1,bcount
     305                 :          84 :      band = ib + bstart - 1
     306         [ +  + ]:        4060 :      do ir=2,nr
     307         [ +  + ]:       55272 :        new%coefs(ir,ib,spin) = inv_rhor(ir) * dot_product(srk(ir,:nkpt-1) - srk(ir,nkpt), lambda(:nkpt-1, ib, spin))
     308                 :             :        !new%coefs(ir,ib,spin) = inv_rhor(ir) * dot_product(lambda(:nkpt-1, ib, spin), conjg(srk(ir,:) - srk(ir,nkpt)))
     309                 :             :        !new%coefs(ir,ib,spin) = inv_rhor(ir) * dot_product(lambda(:nkpt-1, ib, spin), conjg(srk(ir,:) - srk(ir,1)))
     310                 :             :      end do
     311         [ +  + ]:        4067 :      new%coefs(1,ib,spin) = eig(band,nkpt,spin) - dot_product(conjg(new%coefs(2:nr, ib,spin)), srk(2:nr, nkpt))
     312                 :             :    end do
     313                 :             :  end do
     314                 :             : 
     315                 :             :  ! Filter high-frequency.
     316         [ -  + ]:           7 :  if (params(2) > tol6) then
     317                 :           0 :    rcut = params(2) * sqrt(r2vals(new%nr))
     318         [ #  # ]:           0 :    rsigma = params(3); if (rsigma <= zero) rsigma = five
     319                 :           0 :    call wrtout(std_out," Applying filter (Eq 9 of PhysRevB.61.1639)") ! [[cite:Uehara2000]]
     320         [ #  # ]:           0 :    do ir=2,nr
     321   [ #  #  #  # ]:           0 :      new%coefs(ir,:,:) = new%coefs(ir,:,:) * half * abi_derfc((sqrt(r2vals(ir)) - rcut) / rsigma)
     322                 :             :    end do
     323                 :             :  end if
     324                 :             : 
     325                 :             :  ! Prepare workspace arrays for star functions.
     326         [ +  + ]:          28 :  new%cached_kpt = huge(one)
     327   [ -  +  +  -  :          21 :  ABI_MALLOC(new%cached_srk, (new%nr))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     328         [ +  + ]:          28 :  new%cached_kpt_dk1 = huge(one)
     329   [ -  +  +  -  :          21 :  ABI_MALLOC(new%cached_srk_dk1, (new%nr, 3))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     330         [ +  + ]:          28 :  new%cached_kpt_dk2 = huge(one)
     331   [ -  +  +  -  :          28 :  ABI_MALLOC(new%cached_srk_dk2, (new%nr, 3, 3))
          +  -  +  -  +  
          -  -  +  -  +  
                   -  + ]
     332                 :             : 
     333                 :           7 :  ABI_FREE(r2vals)
     334         [ -  + ]:           7 :  ABI_FREE(srk)
     335         [ -  + ]:           7 :  ABI_FREE(inv_rhor)
     336         [ -  + ]:           7 :  ABI_FREE(hmat)
     337         [ -  + ]:           7 :  ABI_FREE(lambda)
     338         [ -  + ]:           7 :  ABI_FREE(ipiv)
     339                 :             : 
     340                 :             :  ! Compare ab-initio data with interpolated results.
     341   [ -  +  +  -  :          21 :  ABI_MALLOC(oeig, (bcount))
          +  -  +  -  -  
                +  -  + ]
     342         [ +  - ]:           7 :  fmt = sjoin("(a,", itoa(bcount), "(es12.4))")
     343                 :           7 :  bstop = bstart + bcount - 1
     344                 :           7 :  mare = zero; mae_meV = zero; cnt = 0
     345                 :           7 :  call wrtout(std_out, ch10//" Comparing ab-initio energies with SKW interpolated results...")
     346         [ +  + ]:          14 :  do spin=1,nsppol
     347         [ +  + ]:          89 :    do ik=1,nkpt
     348         [ -  + ]:          75 :      cnt = cnt + 1; if (mod(cnt, nprocs) /= my_rank) cycle ! mpi parallelism.
     349                 :             : 
     350         [ +  + ]:         887 :      do ib=1,bcount
     351                 :         812 :        band = ib + new%band_block(1) - 1
     352                 :         812 :        call new%eval_bks(band, kpts(:,ik), spin, oeig(ib))
     353                 :             : 
     354                 :         812 :        adiff_meV = abs(eig(band,ik,spin) - oeig(ib)); rel_err = zero
     355         [ +  - ]:         812 :        if (abs(eig(band,ik,spin)) > tol16) rel_err = adiff_meV / abs(eig(band,ik,spin))
     356                 :         812 :        rel_err = 100 * rel_err; adiff_meV = adiff_meV * Ha_meV
     357                 :         887 :        mae_meV = mae_meV + adiff_meV; mare = mare + rel_err
     358                 :             :      end do
     359                 :             : 
     360                 :           7 :      if (prtvol > 0) then
     361   [ +  -  +  + ]:         887 :        ib = imax_loc(eig(bstart:bstop,ik,spin) - oeig)
     362                 :          75 :        rval = (eig(bstart+ib-1,ik,spin) - oeig(ib)) * Ha_meV
     363                 :             :        write(std_out,"(a,es12.4,2a)") &
     364                 :          75 :          " SKW maxerr: ", rval, &
     365                 :         150 :          " (meV), kpt: ", sjoin(ktoa(kpts(:,ik)), "band:",itoa(bstart+ib-1),", spin: ", itoa(spin))
     366                 :             :        !write(std_out,fmt)"-- ref ", eig(bstart:bstop,ik,spin) * Ha_meV
     367                 :             :        !write(std_out,fmt)"-- int ", oeig * Ha_meV
     368                 :             :        !call vdiff%eval(1, bcount, eig(bstart:bstop,ik,spin), oeig, one, unit=std_out))
     369                 :             :      end if
     370                 :             :    end do
     371                 :             :  end do
     372         [ -  + ]:           7 :  ABI_FREE(oeig)
     373                 :             : 
     374                 :             :  ! Issue warning if error too large.
     375         [ +  + ]:          21 :  list2 = [mare, mae_meV]; call xmpi_sum(list2, comm, ierr); mare = list2(1); mae_meV = list2(2)
     376                 :           7 :  cnt = bcount * nkpt * nsppol; mare = mare / cnt; mae_meV = mae_meV / cnt
     377                 :           7 :  write(std_out,"(2(a,es12.4),a,/)")" MARE: ",mare, ", MAE: ", mae_meV, " (meV)"
     378         [ -  + ]:           7 :  if (mae_meV > ten) then
     379                 :             :    write(msg,"(2a,2(a,es12.4),a)") &
     380                 :           0 :      "Large error in SKW interpolation!",ch10," MARE: ",mare, ", MAE: ", mae_meV, " (meV)"
     381                 :           0 :    call wrtout(ab_out, msg)
     382                 :           0 :    ABI_WARNING(msg)
     383                 :             :  end if
     384                 :             : 
     385                 :           7 :  call cwtime_report(" skw_new", cpu_tot, wall_tot, gflops_tot, end_str=ch10)
     386                 :             : 
     387         [ -  + ]:          56 : end function skw_new
     388                 :             : !!***
     389                 :             : 
     390                 :             : !----------------------------------------------------------------------
     391                 :             : 
     392                 :             : !!****f* m_skw/skw_print
     393                 :             : !! NAME
     394                 :             : !!  skw_print
     395                 :             : !!
     396                 :             : !! FUNCTION
     397                 :             : !!  Print info on object
     398                 :             : !!
     399                 :             : !! INPUTS
     400                 :             : !!  unt=Fortran unit number.
     401                 :             : !!
     402                 :             : !! OUTPUT
     403                 :             : !!  only writing
     404                 :             : !!
     405                 :             : !! SOURCE
     406                 :             : 
     407                 :           7 : subroutine skw_print(skw, unt)
     408                 :             : 
     409                 :             : !Arguments ------------------------------------
     410                 :             : !scalars
     411                 :             :  class(skw_t),intent(in) :: skw
     412                 :             :  integer,intent(in) :: unt
     413                 :             : 
     414                 :             : ! *********************************************************************
     415                 :             : 
     416                 :           7 :  write(unt,"(a)")" === Shankland-Koelling-Wood Fourier interpolation scheme ==="
     417                 :           7 :  write(unt,"(a)")sjoin(" nsppol", itoa(skw%nsppol), ", cplex:", itoa(skw%cplex))
     418                 :           7 :  write(unt,"(a)")sjoin(" Number of ab-initio k-points:", itoa(skw%nkpt))
     419                 :           7 :  write(unt,"(a)")sjoin(" Number of star functions:", itoa(skw%nr))
     420                 :           7 :  write(unt,"(a)")sjoin(" Stars/Nk ratio:", ftoa(skw%nr * one / skw%nkpt))
     421                 :           7 :  write(unt,"(a)")sjoin(" Has spatial inversion:", yesno(skw%has_inversion))
     422                 :             : 
     423                 :           7 : end subroutine skw_print
     424                 :             : !!***
     425                 :             : 
     426                 :             : !----------------------------------------------------------------------
     427                 :             : 
     428                 :             : !!****f* m_skw/skw_ncwrite
     429                 :             : !! NAME
     430                 :             : !! skw_ncwrite
     431                 :             : !!
     432                 :             : !! FUNCTION
     433                 :             : !!   Write the object in netcdf format
     434                 :             : !!
     435                 :             : !! INPUTS
     436                 :             : !!  ncid=NC file handle.
     437                 :             : !!  [prefix]=String prepended to netcdf dimensions/variables (HDF5 poor-man groups)
     438                 :             : !!   "skw" if not specified.
     439                 :             : !!
     440                 :             : !! OUTPUT
     441                 :             : !!  Only writing
     442                 :             : !!
     443                 :             : !! SOURCE
     444                 :             : 
     445                 :           0 : integer function skw_ncwrite(self, ncid, prefix) result(ncerr)
     446                 :             : 
     447                 :             : !Arguments ------------------------------------
     448                 :             : !scalars
     449                 :             :  class(skw_t),intent(in) :: self
     450                 :             :  integer,intent(in) :: ncid
     451                 :             :  character(len=*),optional,intent(in) :: prefix
     452                 :             : 
     453                 :             : !Local variables-------------------------------
     454                 :             : !scalars
     455                 :             :  character(len=500) :: prefix_
     456                 :             : !arrays
     457                 :           0 :  real(dp),allocatable :: real_coefs(:,:,:,:)
     458                 :             : ! *************************************************************************
     459                 :             : 
     460         [ #  # ]:           0 :  prefix_ = "skw"; if (present(prefix)) prefix_ = trim(prefix)
     461                 :             : 
     462                 :             :  ! Define dimensions.
     463                 :             :  ncerr = nctk_def_dims(ncid, [ &
     464                 :             :    nctkdim_t("nr", self%nr), nctkdim_t("nkpt", self%nkpt), nctkdim_t("bcount", self%bcount), &
     465                 :             :    nctkdim_t("nsppol", self%nsppol)], &
     466         [ #  # ]:           0 :    defmode=.True., prefix=prefix_)
     467         [ #  # ]:           0 :  NCF_CHECK(ncerr)
     468                 :             : 
     469                 :             :  ncerr = nctk_def_arrays(ncid, [ &
     470                 :             :   ! Atomic structure and symmetry operations
     471                 :             :   nctkarr_t("rpts", "dp", "three, number_of_cartesian_directions, number_of_vectors"), &
     472                 :             :   nctkarr_t("kpts", "dp", "three, nkpt"), &
     473                 :             :   nctkarr_t("coefs", "dp", "two, nr, bcount, nsppol") &
     474         [ #  # ]:           0 :  ], prefix=prefix_)
     475         [ #  # ]:           0 :  NCF_CHECK(ncerr)
     476                 :             : 
     477                 :             :  ! Write data.
     478         [ #  # ]:           0 :  NCF_CHECK(nctk_set_datamode(ncid))
     479         [ #  # ]:           0 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, pre("rpts")), self%rpts))
     480                 :             :  !NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, pre("kpts")), self%kpts))
     481   [ #  #  #  #  :           0 :  ABI_MALLOC(real_coefs, (2, self%nr, self%bcount, self%nsppol))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     482   [ #  #  #  #  :           0 :  real_coefs(1,:,:,:) = real(self%coefs); real_coefs(2,:,:,:) = aimag(self%coefs)
          #  #  #  #  #  
                #  #  # ]
     483         [ #  # ]:           0 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, pre("coefs")), real_coefs))
     484   [ #  #  #  # ]:           0 :  ABI_FREE(real_coefs)
     485                 :             : 
     486                 :             : contains
     487                 :           0 :   pure function pre(istr) result(ostr)
     488                 :             :     character(len=*),intent(in) :: istr
     489                 :             :     character(len=len_trim(prefix_) + len_trim(istr)+1) :: ostr
     490   [ #  #  #  # ]:           0 :     ostr = trim(prefix_) // trim(istr)
     491                 :           0 :   end function pre
     492                 :             : 
     493                 :             : end function skw_ncwrite
     494                 :             : !!***
     495                 :             : 
     496                 :             : !!****f* m_skw/skw_eval_bks
     497                 :             : !! NAME
     498                 :             : !!  skw_eval_bks
     499                 :             : !!
     500                 :             : !! FUNCTION
     501                 :             : !!  Interpolate the energies for an arbitrary k-point and spin with slow FT.
     502                 :             : !!
     503                 :             : !! INPUTS
     504                 :             : !!  band=Band index (global index associated to the input eigenvalues, i.e. independent of band_block)
     505                 :             : !!  kpt(3)=K-point in reduced coordinates.
     506                 :             : !!  spin=Spin index.
     507                 :             : !!
     508                 :             : !! OUTPUT
     509                 :             : !!  oeig=interpolated eigenvalues
     510                 :             : !!    Note that oeig is not necessarily sorted in ascending order.
     511                 :             : !!    The routine does not reorder the interpolated eigenvalues
     512                 :             : !!    to be consistent with the interpolation of the derivatives.
     513                 :             : !!  [oder1(3)]=First-order derivatives wrt k in reduced coordinates.
     514                 :             : !!  [oder2(3,3)]=Second-order derivatives wrt k in reduced coordinates.
     515                 :             : !!
     516                 :             : !! SOURCE
     517                 :             : 
     518                 :       13594 : subroutine skw_eval_bks(skw, band, kpt, spin, oeig, oder1, oder2)
     519                 :             : 
     520                 :             : !Arguments ------------------------------------
     521                 :             : !scalars
     522                 :             :  integer,intent(in) :: band,spin
     523                 :             :  class(skw_t),intent(inout) :: skw
     524                 :             : !arrays
     525                 :             :  real(dp),intent(in) :: kpt(3)
     526                 :             :  real(dp),intent(out) :: oeig
     527                 :             :  real(dp),optional,intent(out) :: oder1(3),oder2(3,3)
     528                 :             : 
     529                 :             : !Local variables-------------------------------
     530                 :             : !scalars
     531                 :             :  integer :: ii,jj,ib
     532                 :             : ! *********************************************************************
     533                 :             : 
     534                 :       13594 :  ib = band - skw%band_block(1) + 1
     535   [ +  -  -  + ]:       13594 :  ABI_CHECK(ib >= 1 .and. ib <= skw%bcount, sjoin("out of range band:", itoa(band)))
     536                 :             : 
     537                 :             :  ! Compute star function for this k-point (if not already in memory)
     538   [ +  +  +  +  :       51165 :  if (any(kpt /= skw%cached_kpt)) then
                   +  + ]
     539                 :        1118 :    call mkstar(skw, kpt, skw%cached_srk)
     540         [ +  + ]:        4472 :    skw%cached_kpt = kpt
     541                 :             :  end if
     542                 :             : 
     543         [ +  + ]:      860874 :  oeig = dot_product(conjg(skw%coefs(:,ib,spin)), skw%cached_srk)
     544                 :             : 
     545                 :             :  ! TODO: Test Derivatives
     546         [ -  + ]:       13594 :  if (present(oder1)) then
     547                 :             :    ! Compute first-order derivatives.
     548   [ #  #  #  #  :           0 :    if (any(kpt /= skw%cached_kpt_dk1)) then
                   #  # ]
     549                 :           0 :      call mkstar_dk1(skw, kpt, skw%cached_srk_dk1)
     550         [ #  # ]:           0 :      skw%cached_kpt_dk1 = kpt
     551                 :             :    end if
     552                 :             : 
     553         [ #  # ]:           0 :    do ii=1,3
     554         [ #  # ]:           0 :      oder1(ii) = dot_product(conjg(skw%coefs(:,ib,spin)), skw%cached_srk_dk1(:,ii)) * two_pi
     555                 :             :    end do
     556                 :             :  end if
     557                 :             : 
     558         [ -  + ]:       13594 :  if (present(oder2)) then
     559                 :             :    ! Compute second-order derivatives.
     560   [ #  #  #  #  :           0 :    if (any(kpt /= skw%cached_kpt_dk2)) then
                   #  # ]
     561                 :           0 :      call mkstar_dk2(skw, kpt, skw%cached_srk_dk2)
     562         [ #  # ]:           0 :      skw%cached_kpt_dk2 = kpt
     563                 :             :    end if
     564                 :             : 
     565                 :           0 :    oder2 = zero
     566         [ #  # ]:           0 :    do jj=1,3
     567         [ #  # ]:           0 :      do ii=1,jj
     568         [ #  # ]:           0 :        oder2(ii, jj) = dot_product(conjg(skw%coefs(:,ib,spin)), skw%cached_srk_dk2(:,ii,jj)) * two_pi**2
     569         [ #  # ]:           0 :        if (ii /= jj) oder2(jj, ii) = oder2(ii, jj)
     570                 :             :      end do
     571                 :             :    end do
     572                 :             :  end if
     573                 :             : 
     574                 :       13594 : end subroutine skw_eval_bks
     575                 :             : !!***
     576                 :             : 
     577                 :             : !----------------------------------------------------------------------
     578                 :             : 
     579                 :             : !!****f* m_skw/skw_free
     580                 :             : !! NAME
     581                 :             : !!  skw_free
     582                 :             : !!
     583                 :             : !! FUNCTION
     584                 :             : !!  Free memory
     585                 :             : !!
     586                 :             : !! SOURCE
     587                 :             : 
     588                 :           7 : subroutine skw_free(skw)
     589                 :             : 
     590                 :             : !Arguments ------------------------------------
     591                 :             : !scalars
     592                 :             :  class(skw_t),intent(inout) :: skw
     593                 :             : 
     594                 :             : ! *********************************************************************
     595                 :             : 
     596         [ +  - ]:           7 :  ABI_SFREE(skw%rpts)
     597         [ +  - ]:           7 :  ABI_SFREE(skw%ptg_symrel)
     598         [ +  - ]:           7 :  ABI_SFREE(skw%ptg_symrec)
     599         [ +  - ]:           7 :  ABI_SFREE(skw%coefs)
     600                 :             : 
     601         [ +  - ]:           7 :  ABI_SFREE(skw%cached_srk)
     602         [ +  + ]:          28 :  skw%cached_kpt = huge(one)
     603         [ +  - ]:           7 :  ABI_SFREE(skw%cached_srk_dk1)
     604         [ +  + ]:          28 :  skw%cached_kpt_dk1 = huge(one)
     605         [ +  - ]:           7 :  ABI_SFREE(skw%cached_srk_dk2)
     606         [ +  + ]:          28 :  skw%cached_kpt_dk2 = huge(one)
     607                 :             : 
     608                 :           7 : end subroutine skw_free
     609                 :             : !!***
     610                 :             : 
     611                 :             : !----------------------------------------------------------------------
     612                 :             : 
     613                 :             : !!****f* m_skw/mkstar
     614                 :             : !! NAME
     615                 :             : !!  mkstar
     616                 :             : !!
     617                 :             : !! FUNCTION
     618                 :             : !!  Compute the star function for k-point kpt
     619                 :             : !!
     620                 :             : !! INPUTS
     621                 :             : !!  kpt(3)=K-point in reduced coordinates.
     622                 :             : !!
     623                 :             : !! OUTPUT
     624                 :             : !!  srk(%nr)=Star function for this k-point.
     625                 :             : !!
     626                 :             : !! SOURCE
     627                 :             : 
     628                 :        1193 : subroutine mkstar(skw, kpt, srk)
     629                 :             : 
     630                 :             : !Arguments ------------------------------------
     631                 :             : !scalars
     632                 :             :  type(skw_t),intent(in) :: skw
     633                 :             : !arrays
     634                 :             :  real(dp),intent(in) :: kpt(3)
     635                 :             :  complex(dp),intent(out) :: srk(skw%nr)
     636                 :             : 
     637                 :             : !Local variables-------------------------------
     638                 :             : !scalars
     639                 :             :  integer :: ir,isym
     640                 :             : !arrays
     641                 :             :  real(dp) :: sk(3)
     642                 :             : ! *********************************************************************
     643                 :             : 
     644         [ +  + ]:       92893 :  srk = zero
     645         [ +  + ]:       58457 :  do isym=1,skw%ptg_nsym
     646   [ +  +  +  +  :     1660656 :    sk = two_pi * matmul(transpose(skw%ptg_symrel(:,:,isym)), kpt)
          +  +  +  +  +  
                -  +  + ]
     647         [ +  + ]:     4460057 :    do ir=1,skw%nr
     648         [ +  + ]:    17663664 :      srk(ir) = srk(ir) + exp(j_dpc * dot_product(sk, skw%rpts(:,ir)))
     649                 :             :    end do
     650                 :             :  end do
     651         [ +  + ]:       92893 :  srk = srk / skw%ptg_nsym
     652                 :             : 
     653                 :        1193 : end subroutine mkstar
     654                 :             : !!***
     655                 :             : 
     656                 :             : !----------------------------------------------------------------------
     657                 :             : 
     658                 :             : !!****f* m_skw/mkstar_dk1
     659                 :             : !! NAME
     660                 :             : !!  mkstar_dk1
     661                 :             : !!
     662                 :             : !! FUNCTION
     663                 :             : !!  Compute the 1st derivative of the star function wrt k
     664                 :             : !!
     665                 :             : !! INPUTS
     666                 :             : !!  kpt(3)=K-point in reduced coordinates.
     667                 :             : !!
     668                 :             : !! OUTPUT
     669                 :             : !!  srk_dk1(%nr,3)=Derivative of the star function wrt k in reduced coordinates.
     670                 :             : !!
     671                 :             : !! SOURCE
     672                 :             : 
     673                 :           0 : subroutine mkstar_dk1(skw, kpt, srk_dk1)
     674                 :             : 
     675                 :             : !Arguments ------------------------------------
     676                 :             : !scalars
     677                 :             :  type(skw_t),intent(in) :: skw
     678                 :             : !arrays
     679                 :             :  real(dp),intent(in) :: kpt(3)
     680                 :             :  complex(dp),intent(out) :: srk_dk1(skw%nr,3)
     681                 :             : 
     682                 :             : !Local variables-------------------------------
     683                 :             : !scalars
     684                 :             :  integer :: ir,isym
     685                 :             : !arrays
     686                 :             :  real(dp) :: sk(3)
     687                 :           0 :  complex(dp) :: work(3,skw%nr)
     688                 :             : ! *********************************************************************
     689                 :             : 
     690   [ #  #  #  # ]:           0 :  work = zero
     691         [ #  # ]:           0 :  do isym=1,skw%ptg_nsym
     692   [ #  #  #  #  :           0 :    sk = two_pi * matmul(transpose(skw%ptg_symrel(:,:,isym)), kpt)
          #  #  #  #  #  
                #  #  # ]
     693         [ #  # ]:           0 :    do ir=1,skw%nr
     694                 :             :      work(:,ir) = work(:,ir) + exp(j_dpc * dot_product(sk, skw%rpts(:,ir))) * &
     695   [ #  #  #  #  :           0 :         matmul(skw%ptg_symrel(:,:,isym), skw%rpts(:,ir))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     696                 :             :    end do
     697                 :             :  end do
     698   [ #  #  #  # ]:           0 :  work = j_dpc * work / skw%ptg_nsym
     699   [ #  #  #  # ]:           0 :  srk_dk1 = transpose(work)
     700                 :             : 
     701                 :           0 : end subroutine mkstar_dk1
     702                 :             : !!***
     703                 :             : 
     704                 :             : !----------------------------------------------------------------------
     705                 :             : 
     706                 :             : !!****f* m_skw/mkstar_dk2
     707                 :             : !! NAME
     708                 :             : !!  mkstar_dk2
     709                 :             : !!
     710                 :             : !! FUNCTION
     711                 :             : !!  Compute the 2st derivatives of the star function wrt k
     712                 :             : !!
     713                 :             : !! INPUTS
     714                 :             : !!  kpt(3)=K-point in reduced coordinates.
     715                 :             : !!
     716                 :             : !! OUTPUT
     717                 :             : !!  srk_dk2(%nr,3,3)=2nd derivatives of the star function wrt k in reduced coordinates.
     718                 :             : !!
     719                 :             : !! SOURCE
     720                 :             : 
     721                 :           0 : subroutine mkstar_dk2(skw, kpt, srk_dk2)
     722                 :             : 
     723                 :             : !Arguments ------------------------------------
     724                 :             : !scalars
     725                 :             :  type(skw_t),intent(in) :: skw
     726                 :             : !arrays
     727                 :             :  real(dp),intent(in) :: kpt(3)
     728                 :             :  complex(dp),intent(out) :: srk_dk2(skw%nr,3,3)
     729                 :             : 
     730                 :             : !Local variables-------------------------------
     731                 :             : !scalars
     732                 :             :  integer :: ir,isym,ii,jj
     733                 :             :  complex(dp) :: eiskr
     734                 :             : !arrays
     735                 :             :  integer :: sr(3)
     736                 :             :  real(dp) :: sk(3)
     737                 :           0 :  complex(dp) :: work(3,3,skw%nr)
     738                 :             : ! *********************************************************************
     739                 :             : 
     740   [ #  #  #  #  :           0 :  work = zero
                   #  # ]
     741         [ #  # ]:           0 :  do isym=1,skw%ptg_nsym
     742   [ #  #  #  #  :           0 :    sk = two_pi * matmul(transpose(skw%ptg_symrel(:,:,isym)), kpt)
          #  #  #  #  #  
                #  #  # ]
     743         [ #  # ]:           0 :    do ir=1,skw%nr
     744   [ #  #  #  #  :           0 :      sr = matmul(skw%ptg_symrel(:,:,isym), skw%rpts(:,ir))
          #  #  #  #  #  
                      # ]
     745         [ #  # ]:           0 :      eiskr = exp(j_dpc * dot_product(sk, skw%rpts(:,ir)))
     746         [ #  # ]:           0 :      do jj=1,3
     747         [ #  # ]:           0 :        do ii=1,jj
     748                 :           0 :          work(ii,jj,ir) = work(ii,jj,ir) + eiskr * sr(ii) * sr(jj)
     749                 :             :        end do
     750                 :             :      end do
     751                 :             :    end do
     752                 :             :  end do
     753   [ #  #  #  #  :           0 :  work = - work / skw%ptg_nsym
                   #  # ]
     754                 :             : 
     755         [ #  # ]:           0 :  do jj=1,3
     756         [ #  # ]:           0 :    do ii=1,jj
     757         [ #  # ]:           0 :      srk_dk2(:, ii, jj) = work(ii, jj, :)
     758   [ #  #  #  # ]:           0 :      if (ii /= jj) srk_dk2(:,jj,ii) = work(:,ii,jj)
     759                 :             :    end do
     760                 :             :  end do
     761                 :             : 
     762                 :           0 : end subroutine mkstar_dk2
     763                 :             : !!***
     764                 :             : 
     765                 :             : !----------------------------------------------------------------------
     766                 :             : 
     767                 :             : !!****f* m_skw/find_rstar_gen
     768                 :             : !! NAME
     769                 :             : !!  find_rstar_gen
     770                 :             : !!
     771                 :             : !! FUNCTION
     772                 :             : !!  Find the R-space points generating the stars.
     773                 :             : !!  Set skw%nr and skw%rpts.
     774                 :             : !!
     775                 :             : !! INPUTS
     776                 :             : !!  cryst<crystal_t>=Crystalline structure.
     777                 :             : !!  nrwant=Number of R-space points wanted
     778                 :             : !!  rmax(3)=Max reduced components of supercell.
     779                 :             : !!  comm=MPI communicator.
     780                 :             : !!
     781                 :             : !! OUTPUT
     782                 :             : !!  or2vals(skw%nr)=||R||**2
     783                 :             : !!
     784                 :             : !! SOURCE
     785                 :             : 
     786                 :           7 : subroutine find_rstar_gen(skw, cryst, nrwant, rmax, or2vals, comm)
     787                 :             : 
     788                 :             : !Arguments ------------------------------------
     789                 :             : !scalars
     790                 :             :  type(skw_t),intent(inout) :: skw
     791                 :             :  type(crystal_t),intent(in) :: cryst
     792                 :             :  integer,intent(in) :: nrwant,comm
     793                 :             : !arrays
     794                 :             :  integer,intent(in) :: rmax(3)
     795                 :             :  real(dp),allocatable,intent(out) :: or2vals(:)
     796                 :             : 
     797                 :             : !Local variables-------------------------------
     798                 :             : !scalars
     799                 :             :  integer :: cnt,nstars,i1,i2,i3,msize,ir,nsh,ish,ss,ee,nst,ierr,nprocs,my_rank,ii
     800                 :             :  real(dp) :: r2_prev
     801                 :             :  !character(len=500) :: msg
     802                 :             : !arrays
     803                 :           7 :  integer,allocatable :: iperm(:),rtmp(:,:),rgen(:,:),r2sh(:),shlim(:),sh_start(:),sh_stop(:)
     804                 :           7 :  integer,allocatable :: recvcounts(:),displs(:),recvbuf(:,:)
     805                 :           7 :  real(dp),allocatable :: r2tmp(:),cnorm(:)
     806                 :             : 
     807                 :             : ! *********************************************************************
     808                 :             : 
     809                 :           7 :  nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
     810                 :             : 
     811         [ +  + ]:          28 :  msize = product(2*rmax + 1)
     812   [ -  +  +  -  :          21 :  ABI_MALLOC(rtmp, (3, msize))
          +  -  +  -  -  
                +  -  + ]
     813   [ -  +  +  -  :          21 :  ABI_MALLOC(r2tmp, (msize))
          +  -  +  -  -  
                +  -  + ]
     814                 :             : 
     815                 :           7 :  cnt = 0
     816         [ +  + ]:         132 :  do i3=-rmax(3),rmax(3)
     817         [ +  + ]:        2427 :    do i2=-rmax(2),rmax(2)
     818         [ +  + ]:       45985 :      do i1=-rmax(1),rmax(1)
     819                 :       43565 :        cnt = cnt + 1
     820         [ +  + ]:      174260 :        rtmp(:, cnt) = [i1,i2,i3]
     821   [ +  +  +  +  :      873595 :        r2tmp(cnt) = dot_product(rtmp(:,cnt), matmul(cryst%rmet, rtmp(:,cnt)))
          +  +  +  -  +  
                      + ]
     822                 :             :      end do
     823                 :             :    end do
     824                 :             :  end do
     825                 :             : 
     826                 :             :  ! Sort r2tmp
     827   [ -  +  +  -  :          21 :  ABI_MALLOC(iperm, (msize))
          +  -  +  -  -  
                +  -  + ]
     828   [ +  -  +  +  :      130716 :  iperm = [(i1, i1=1,msize)]
          +  -  +  +  +  
          -  -  +  -  -  
                   +  + ]
     829                 :           7 :  call sort_dp(msize, r2tmp, iperm, tol12)
     830                 :             : 
     831                 :             :  ! Find R-points generating the stars.
     832   [ -  +  +  -  :          14 :  ABI_MALLOC(rgen, (3, msize))
             -  +  -  + ]
     833         [ +  + ]:       43572 :  do ir=1,msize
     834         [ +  + ]:      174267 :    rgen(:,ir) = rtmp(:,iperm(ir))
     835                 :             :  end do
     836   [ -  +  +  +  :      174274 :  rtmp = rgen
                   +  + ]
     837         [ -  + ]:           7 :  ABI_FREE(iperm)
     838                 :             : 
     839   [ -  +  +  -  :          14 :  ABI_MALLOC(r2sh, (msize))     ! Correspondence between R and the shell index.
             -  +  -  + ]
     840   [ +  -  -  +  :          21 :  ABI_MALLOC(shlim, (msize+1))  ! For each shell, the index of the initial G-vector.
          +  -  +  -  +  
             -  -  +  -  
                      + ]
     841                 :           7 :  nsh = 1; r2sh(1) = 1; shlim(1) = 1; r2_prev = zero
     842         [ +  + ]:       43565 :  do ir=2,msize
     843         [ +  + ]:       43558 :    if (abs(r2tmp(ir) - r2_prev) > r2tmp(ir) * tol8) then
     844                 :        1447 :      r2_prev = r2tmp(ir); nsh = nsh + 1; shlim(nsh) = ir
     845                 :             :      !write(std_out,*)"nsh: ",shlim(nsh) - shlim(nsh-1)
     846                 :             :    end if
     847                 :       43565 :    r2sh(ir) = nsh
     848                 :             :  end do
     849                 :           7 :  shlim(nsh+1) = msize + 1
     850         [ -  + ]:           7 :  ABI_FREE(r2tmp)
     851                 :           7 :  ABI_FREE(r2sh)
     852                 :             : 
     853                 :             :  !call get_irredg(msize, skw%ptg_nsym, +1, cryst%rprimd, skw%ptg_symrel, rtmp, nstars, rgen, cnorm)
     854                 :             :  !write(66,*)nstars; do ish=1,nstars; write(66,*)rgen(:,ish); end do
     855                 :             : 
     856                 :             :  ! Distribute shells among processor so that we can parallelize the search algorithm.
     857                 :             :  ! Each proc works on a contigous block of shells, then we have to gather the results.
     858   [ -  +  +  -  :          21 :  ABI_MALLOC(sh_start, (0:nprocs-1))
          +  -  +  -  -  
                +  -  + ]
     859   [ -  +  +  -  :          14 :  ABI_MALLOC(sh_stop, (0:nprocs-1))
             -  +  -  + ]
     860                 :           7 :  call xmpi_split_work2_i4b(nsh, nprocs, sh_start, sh_stop)
     861                 :             : 
     862   [ -  +  +  -  :          14 :  ABI_MALLOC(cnorm, (msize))
             -  +  -  + ]
     863                 :           7 :  nstars = 0
     864         [ +  + ]:        1461 :  do ish=sh_start(my_rank),sh_stop(my_rank)
     865                 :        1454 :    ss = shlim(ish); ee = shlim(ish+1) - 1; msize = ee - ss + 1
     866                 :             :    call get_irredg(msize, skw%ptg_nsym, + 1, cryst%rprimd, skw%ptg_symrel, rtmp(:,ss:), &
     867                 :        1454 :      nst, rgen(:,nstars+1:), cnorm(nstars+1:))
     868                 :        1461 :    nstars = nstars + nst
     869                 :             :  end do
     870                 :             : 
     871         [ -  + ]:           7 :  ABI_FREE(cnorm)
     872                 :           7 :  ABI_FREE(sh_start)
     873                 :           7 :  ABI_FREE(sh_stop)
     874         [ -  + ]:           7 :  ABI_FREE(rtmp)
     875                 :           7 :  ABI_FREE(shlim)
     876                 :             : 
     877         [ -  + ]:           7 :  if (nprocs > 1) then
     878                 :             :    ! Collect star functions.
     879   [ #  #  #  #  :           0 :    ABI_MALLOC(recvcounts, (nprocs))
          #  #  #  #  #  
                      # ]
     880         [ #  # ]:           0 :    recvcounts = 0; recvcounts(my_rank+1) = 3 * nstars
     881                 :           0 :    call xmpi_sum(recvcounts, comm, ierr)
     882   [ #  #  #  #  :           0 :    ABI_MALLOC(displs, (nprocs))
             #  #  #  # ]
     883                 :           0 :    displs(1) = 0
     884         [ #  # ]:           0 :    do ii=2,nprocs
     885         [ #  # ]:           0 :      displs(ii) = sum(recvcounts(:ii-1))
     886                 :             :    end do
     887                 :           0 :    call xmpi_sum(nstars, nst, comm, ierr)   ! Now nst is the total number of star functions.
     888   [ #  #  #  #  :           0 :    ABI_MALLOC(recvbuf, (3, nst))
          #  #  #  #  #  
                #  #  # ]
     889                 :           0 :    call xmpi_allgatherv(rgen, 3*nstars, recvbuf, recvcounts, displs, comm, ierr)
     890         [ #  # ]:           0 :    ABI_FREE(recvcounts)
     891                 :           0 :    ABI_FREE(displs)
     892                 :           0 :    nstars = nst
     893   [ #  #  #  # ]:           0 :    rgen(:,1:nstars) = recvbuf
     894         [ #  # ]:           0 :    ABI_FREE(recvbuf)
     895                 :             :  end if
     896                 :             :  !if (my_rank == 0) then
     897                 :             :  !  write(67,*)"nstars",nstars,"nsh",nsh; do ish=1,nstars; write(67,*)rgen(:,ish); end do
     898                 :             :  !end if
     899                 :             : 
     900                 :             :  ! Store rpts and compute ||R||**2.
     901                 :           7 :  skw%nr = min(nstars, nrwant)
     902         [ -  + ]:           7 :  if (allocated(skw%rpts)) then
     903                 :           0 :    ABI_FREE(skw%rpts)
     904                 :             :  end if
     905   [ -  +  +  -  :          21 :  ABI_MALLOC(skw%rpts, (3, skw%nr))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     906   [ -  +  +  +  :        1514 :  skw%rpts = rgen(:,1:skw%nr)
                   +  + ]
     907   [ -  +  +  -  :          21 :  ABI_MALLOC(or2vals, (skw%nr))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     908         [ +  + ]:         382 :  do ir=1,skw%nr
     909   [ +  +  +  +  :        7507 :    or2vals(ir) = dot_product(skw%rpts(:,ir), matmul(cryst%rmet, skw%rpts(:,ir)))
          +  +  +  -  +  
                      + ]
     910                 :             :  end do
     911                 :             : 
     912         [ -  + ]:           7 :  ABI_FREE(rgen)
     913                 :             : 
     914   [ -  +  -  +  :           7 : end subroutine find_rstar_gen
                   -  + ]
     915                 :             : !!***
     916                 :             : 
     917   [ -  -  #  #  :      101204 : end module m_skw
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     918                 :             : !!***
        

Generated by: LCOV version 2.3-1