LCOV - code coverage report
Current view: top level - src/79_seqpar_mpi - m_slicewf_cprj.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 62 0
Test Date: 2026-09-19 15:24:51 Functions: 0.0 % 3 0

            Line data    Source code
       1              : !!****f* ABINIT/m_slicewf_cprj
       2              : !! NAME
       3              : !! m_slicewf_cprj
       4              : !!
       5              : !! FUNCTION
       6              : !! This module contains a routine updating the whole wave functions at a given k-point,
       7              : !! using the Spectrum Slicing filtering method (2021 implementation using xG abstraction layer)
       8              : !! for a given spin-polarization, from a fixed hamiltonian
       9              : !! but might also simply compute eigenvectors and eigenvalues at this k point.
      10              : !! it will also update the matrix elements of the hamiltonian.
      11              : !!
      12              : !! COPYRIGHT
      13              : !! Copyright (C) 2023-2025 ABINIT group (LB,IML)
      14              : !! This file is distributed under the terms of the
      15              : !! gnu general public license, see ~abinit/COPYING
      16              : !! or http://www.gnu.org/copyleft/gpl.txt .
      17              : !! for the initials of contributors, see ~abinit/doc/developers/contributors.txt .
      18              : !!
      19              : !! PARENTS
      20              : !!      vtowfk
      21              : !!
      22              : !! CHILDREN
      23              : !!
      24              : !! SOURCE
      25              : 
      26              : #if defined HAVE_CONFIG_H
      27              : #include "config.h"
      28              : #endif
      29              : 
      30              : #include "abi_common.h"
      31              : 
      32              : module m_slicewf_cprj
      33              : 
      34              :  use defs_abitypes
      35              :  use defs_basis
      36              :  use m_abicore
      37              :  use m_errors
      38              :  use m_fstrings
      39              :  use m_time
      40              :  use m_xg
      41              :  use m_xg_nonlop
      42              :  use m_slice_cprj
      43              :  use m_invovl
      44              : 
      45              :  use m_dtset,       only : dataset_type
      46              :  use m_hamiltonian, only : gs_hamiltonian_type
      47              :  use m_pawcprj,     only : pawcprj_type
      48              :  use m_getghc,      only : multithreaded_getghc
      49              : 
      50              :  use m_xg
      51              :  use m_xgTransposer
      52              : 
      53              :  use iso_c_binding, only: c_associated,c_loc,c_ptr,c_f_pointer
      54              : 
      55              :  use m_xmpi
      56              :  use m_xomp
      57              : #ifdef HAVE_OPENMP
      58              :  use omp_lib
      59              : #endif
      60              : 
      61              :  implicit none
      62              : 
      63              :  private
      64              : 
      65              :  integer, parameter :: l_tim_getghc=5
      66              : 
      67              : ! For use in getghc_gsc1
      68              :  integer, save :: l_prtvol
      69              :  type(mpi_type),pointer,save :: l_mpi_enreg
      70              :  type(gs_hamiltonian_type),pointer,save :: l_gs_hamk
      71              : 
      72              :  public :: slicewf_cprj
      73              : 
      74              :  contains
      75              : !!***
      76              : 
      77              : !!****f* m_slicewf/slicewf_cprj
      78              : !! NAME
      79              : !! slicewf_cprj
      80              : !!
      81              : !! FUNCTION
      82              : !! This routine updates the whole wave functions set at a given k-point,
      83              : !! using the Spectrum Slicing method (2021 version using xG abstraction layer)
      84              : !!
      85              : !! INPUTS
      86              : !!  dtset= input variables for this dataset
      87              : !!  mpi_enreg= MPI-parallelisation information
      88              : !!  nband= number of bands at this k point
      89              : !!  npw= number of plane waves at this k point
      90              : !!  nspinor= number of spinorial components of the wavefunctions
      91              : !!  prtvol= control print volume and debugging
      92              : !!
      93              : !! OUTPUT
      94              : !!  eig(nband)= eigenvalues (hartree) for all bands
      95              : !!  enl_out(nband)= contribution of each band to the nl part of energy
      96              : !!  resid(nband)= residuals for each band
      97              : !!
      98              : !! SIDE EFFECTS
      99              : !!  cg(2,npw*nspinor*nband)= planewave coefficients of wavefunctions
     100              : !!  gs_hamk <type(gs_hamiltonian_type)>=all data for the hamiltonian at k
     101              : !!
     102              : !! SOURCE
     103              : 
     104            0 : subroutine slicewf_cprj(cg,dtset,eig,occ,enl_out,gs_hamk,mpi_enreg,&
     105            0 : &                   nband,npw,nspinor,prtvol,resid,xg_nonlop)
     106              : 
     107              : !Arguments ------------------------------------
     108              :  integer,intent(in) :: nband,npw,prtvol,nspinor
     109              :  type(gs_hamiltonian_type),target,intent(inout) :: gs_hamk
     110              :  type(dataset_type)              ,intent(in   ) :: dtset
     111              :  type(mpi_type)           ,target,intent(in)    :: mpi_enreg
     112              :  real(dp)                 ,target,intent(inout) :: cg(2,nspinor*nband*npw)
     113              :  real(dp)                 ,target,intent(  out) :: resid(nband)
     114              :  real(dp)                        ,intent(  out) :: enl_out(nband)
     115              :  real(dp)                 ,target,intent(  out) :: eig(nband)
     116              :  real(dp)                 ,target,intent(in   ) :: occ(nband)
     117              :  type(xg_nonlop_t)        ,       intent(in   ) :: xg_nonlop
     118              : 
     119              : !Local variables-------------------------------
     120              : 
     121              :  type(xgBlock_t) :: xgx0
     122              :  type(xg_t) :: cprj_xgx0
     123              :  type(xgBlock_t) :: xgeigen
     124              :  type(xgBlock_t) :: xgocc
     125              :  type(xgBlock_t) :: xgresidu
     126              :  type(xgBlock_t) :: xgenl
     127              :  type(xgBlock_t) :: xg_kin
     128            0 :  type(slice_t) :: slice
     129              : 
     130              :  logical :: paw
     131              : 
     132              :  integer :: space, space_cprj, blockdim, cprjdim, nband_cprj
     133              :  integer :: me_g0,me_g0_fft
     134              : 
     135              :  integer, parameter :: tim_slicewf = 2170
     136              :  double precision :: tsec(2)
     137              : 
     138            0 :  real(dp), allocatable :: kin(:),occ_tmp(:)
     139              : 
     140              : ! *********************************************************************
     141              : 
     142            0 :  call timab(tim_slicewf,1,tsec)
     143              : 
     144            0 :  paw = gs_hamk%usepaw==1
     145              : 
     146              :  ! Set module variables
     147            0 :  l_prtvol = prtvol
     148            0 :  l_mpi_enreg => mpi_enreg
     149            0 :  l_gs_hamk => gs_hamk
     150              : 
     151            0 :  cprjdim = xg_nonlop%cprjdim
     152              : 
     153              : !Variables
     154            0 :  blockdim=mpi_enreg%nproc_band*mpi_enreg%bandpp
     155            0 :  nband_cprj=nband/mpi_enreg%nproc_band
     156              : 
     157              : !Depends on istwfk
     158            0 :  if ( gs_hamk%istwf_k > 1 ) then ! Real only
     159              :    ! SPACE_CR mean that we have complex numbers but no re*im terms only re*re
     160              :    ! and im*im so that a vector of complex is consider as a long vector of real
     161              :    ! therefore the number of data is (2*npw*nspinor)*nband
     162              :    ! This space is completely equivalent to SPACE_R but will correctly set and
     163              :    ! get the array data into the xgBlock
     164            0 :    space      = SPACE_CR
     165              :  else ! complex
     166            0 :    space      = SPACE_C
     167              :  end if
     168            0 :  space_cprj = xg_nonlop%space_cprj
     169              : 
     170              :  !For kinetic part of the Hamiltonian
     171            0 :  ABI_MALLOC(kin,(gs_hamk%npw_fft_k))
     172            0 :  call build_kin(kin,gs_hamk%kinpw_k,gs_hamk%npw_fft_k)
     173            0 :  call xgBlock_map_1d(xg_kin,kin,SPACE_R,gs_hamk%npw_fft_k)
     174              : 
     175              :  ! Local variables for slice
     176            0 :  me_g0 = -1
     177            0 :  me_g0_fft = -1
     178            0 :  if (space==SPACE_CR) then
     179            0 :    me_g0 = 0
     180            0 :    me_g0_fft = 0
     181            0 :    if (gs_hamk%istwf_k == 2) then
     182            0 :      if (l_mpi_enreg%me_g0 == 1) me_g0 = 1
     183            0 :      if (l_mpi_enreg%me_g0_fft == 1) me_g0_fft = 1
     184              :    end if
     185              :  end if
     186            0 :  call xgBlock_map(xgx0,cg,space,npw*nspinor,nband,l_mpi_enreg%comm_band,me_g0=me_g0)
     187              : 
     188            0 :  call xgBlock_map_1d(xgeigen,eig,SPACE_R,nband)
     189              : 
     190            0 :  call xgBlock_map_1d(xgresidu,resid,SPACE_R,nband)
     191              : 
     192            0 :  call xgBlock_map_1d(xgenl,enl_out,SPACE_R,nband)
     193              : 
     194              :  ! Occupancies in chebyshev are used for convergence criteria only
     195            0 :  if (dtset%nbdbuf==-101.and.nspinor==1.and.dtset%nsppol==1) then
     196            0 :    ABI_MALLOC(occ_tmp,(nband))
     197            0 :    occ_tmp(:) = half*occ(:)
     198            0 :    call xgBlock_map_1d(xgocc,occ_tmp,SPACE_R,nband,gpu_option=dtset%gpu_option)
     199              :  else
     200            0 :    call xgBlock_map_1d(xgocc,occ,SPACE_R,nband,gpu_option=dtset%gpu_option)
     201              :  end if
     202              : 
     203              :  !call xg_cprj_copy(cprj_cwavef_bands,cprj_contiguous,space_cprj,nband_cprj,cprj_xgx0,&
     204              :  !  & xg_nonlop,l_mpi_enreg%comm_band,CPRJ_ALLOC)
     205            0 :  call xg_init(cprj_xgx0,space_cprj,xg_nonlop%cprjdim,nband_cprj*nspinor,comm=l_mpi_enreg%comm_band)
     206              : 
     207              :  call slice_init(slice,nband,npw*nspinor,cprjdim,dtset%tolwfr_diago,dtset%ecut, &
     208              : &                 mpi_enreg%bandpp, dtset%nline, dtset%nbdbuf, space,space_cprj,1, &
     209              : &                 l_mpi_enreg%comm_band,me_g0,paw,&
     210              : &                 dtset%nslice,0.d0,dtset%paral_slice,0,&
     211            0 : &                 xg_nonlop,me_g0_fft)
     212              : 
     213              :  ! Run slice
     214            0 :  call slice_run_cprj(slice,xgx0,cprj_xgx0%self,xg_getghc,xg_kin,xgeigen,xgocc,xgresidu,xgenl,nspinor)
     215              : 
     216            0 :  if (allocated(occ_tmp)) then
     217            0 :    ABI_FREE(occ_tmp)
     218              :  end if
     219            0 :  ABI_FREE(kin)
     220              : 
     221              : ! call xg_cprj_copy(cprj_cwavef_bands,cprj_contiguous,space_cprj,nband_cprj,cprj_xgx0,&
     222              : !   & xg_nonlop,l_mpi_enreg%comm_band,CPRJ_FREE)
     223            0 :  call xg_free(cprj_xgx0)
     224              : 
     225              :  ! Free slice
     226            0 :  call slice_free(slice)
     227              : 
     228            0 :  call timab(tim_slicewf,2,tsec)
     229              : 
     230              :  DBG_EXIT("COLL")
     231              : 
     232            0 : end subroutine slicewf_cprj
     233              : !!***
     234              : 
     235              : !!****f* m_slice/xg_getghc
     236              : !! NAME
     237              : !! xg_getghc
     238              : !!
     239              : !! FUNCTION
     240              : !! This routine computes H|C> and possibly S|C> for a given wave function C.
     241              : !!  It acts as a driver for getghc, taken into account parallelism, multithreading, etc.
     242              : !!
     243              : !! SIDE EFFECTS
     244              : !!  X  <type(xgBlock_t)>= memory block containing |C>
     245              : !!  AX <type(xgBlock_t)>= memory block containing H|C>
     246              : !!
     247              : !! PARENTS
     248              : !!
     249              : !! CHILDREN
     250              : !!      xgBlock_getSize,xgBlock_reverseMap,xgBlock_scale,xgBlock_copy
     251              : !!      multithreaded_getghc
     252              : !!
     253              : !! SOURCE
     254              : !
     255            0 : subroutine xg_getghc(X,AX)
     256              : 
     257              :  use iso_c_binding
     258              : 
     259              : !Arguments ------------------------------------
     260              :  type(xgBlock_t), intent(inout) :: X
     261              :  type(xgBlock_t), intent(inout) :: AX
     262              : 
     263              : !Local variables-------------------------------
     264              : !scalars
     265              :  integer         :: blockdim
     266              :  integer         :: spacedim
     267              :  integer,parameter :: sij_opt=0,cpopt=-1,type_calc=1 ! Compute local part only
     268              : ! integer :: iatom,iband,ispinor,cprj_index,cprj_rows,cprj_cols,ncpgr,nlmn
     269              :  real(dp) :: eval
     270            0 :  type(pawcprj_type) :: cprj_dum(l_gs_hamk%natom,1)
     271              : !arrays
     272            0 :  real(dp), pointer :: cg(:,:)
     273            0 :  real(dp), pointer :: ghc(:,:)
     274              :  real(dp) :: gsc(1,1),gvnlxc(1,1)
     275              : 
     276              : ! *********************************************************************
     277              : 
     278            0 :  call xgBlock_getSize(X,spacedim,blockdim)
     279            0 :  call xgBlock_check(X,AX)
     280              : 
     281            0 :  call xgBlock_reverseMap(X,cg,rows=1,cols=spacedim*blockdim)
     282            0 :  call xgBlock_reverseMap(AX,ghc,rows=1,cols=spacedim*blockdim)
     283              : 
     284              :  ! Apply only local part of the Hamiltonian
     285              :  call multithreaded_getghc(cpopt,cg,cprj_dum,ghc,gsc,&
     286            0 :    l_gs_hamk,gvnlxc,eval,l_mpi_enreg,blockdim,l_prtvol,sij_opt,l_tim_getghc,type_calc)
     287              : 
     288            0 : end subroutine xg_getghc
     289              : !!***
     290              : 
     291            0 : subroutine build_kin(kin,kinpw,npw)
     292              : 
     293              :   integer,intent(in) :: npw
     294              :   real(dp),intent(in) :: kinpw(:)
     295              :   real(dp),intent(out) :: kin(:)
     296              : 
     297              :   integer :: ipw
     298              : 
     299              :   !$omp parallel do schedule(static), shared(kin,kinpw)
     300            0 :   do ipw=1,npw
     301            0 :     if(kinpw(ipw)>huge(0.0_dp)*1.d-11) then
     302            0 :       kin(ipw)=0.d0
     303              :     else
     304            0 :       kin(ipw) = kinpw(ipw)
     305              :     end if
     306              :   end do
     307              : 
     308            0 : end subroutine build_kin
     309              : 
     310              : end module m_slicewf_cprj
     311              : !!***
        

Generated by: LCOV version 2.3-1