LCOV - code coverage report
Current view: top level - src/80_rttddft - m_rttddft_exponential.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 96.7 % 92 89
Test Date: 2026-09-19 17:42:43 Functions: 100.0 % 2 2

            Line data    Source code
       1              : !!****m* ABINIT/m_rttddft_exponential
       2              : !! NAME
       3              : !!  m_rttddft_exponential
       4              : !!
       5              : !! FUNCTION
       6              : !!  Contains subroutines to compute the exponential
       7              : !!  part of the propagator using various approximations
       8              : !!
       9              : !! COPYRIGHT
      10              : !!  Copyright (C) 2021-2026 ABINIT group (FB)
      11              : !!  This file is distributed under the terms of the
      12              : !!  GNU General Public License, see ~abinit/COPYING
      13              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      14              : !!
      15              : !! SOURCE
      16              : 
      17              : #if defined HAVE_CONFIG_H
      18              : #include "config.h"
      19              : #endif
      20              : 
      21              : #include "abi_common.h"
      22              : 
      23              : module m_rttddft_exponential
      24              : 
      25              :  use defs_basis
      26              :  use defs_abitypes,        only: MPI_type
      27              : 
      28              :  use m_bandfft_kpt,        only: bandfft_kpt, &
      29              :                                & bandfft_kpt_get_ikpt
      30              :  use m_dtset,              only: dataset_type
      31              :  use m_getghc,             only: multithreaded_getghc
      32              :  use m_hamiltonian,        only: gs_hamiltonian_type
      33              :  use m_invovl,             only: apply_invovl
      34              :  use m_pawcprj,            only: pawcprj_type, pawcprj_alloc, pawcprj_free
      35              :  use m_prep_kgb,           only: prep_getghc, prep_index_wavef_bandpp
      36              :  use m_profiling_abi,      only: abimem_record
      37              :  use m_rttddft_properties, only: rttddft_calc_eig, rttddft_calc_enl
      38              :  use m_xmpi,               only: xmpi_alltoallv
      39              : 
      40              :  implicit none
      41              : 
      42              :  private
      43              : !!***
      44              : 
      45              :  public :: rttddft_exp_taylor
      46              : !!***
      47              : 
      48              : contains
      49              : !!***
      50              : 
      51              : !!****f* m_rttddft_exponential/rttddft_exp_taylor
      52              : !!
      53              : !! NAME
      54              : !!  rttddft_propagator_exp
      55              : !!
      56              : !! FUNCTION
      57              : !!  Applies the propagator exp(-i*dt*H(*S^-1)) on the cg coeffs
      58              : !!  approximating the exponential using a Taylor exapansion
      59              : !!
      60              : !! INPUTS
      61              : !!  cg <real(npw*nspinor*nband)> = the wavefunction coefficients
      62              : !!  dtset <type(dataset_type)>=all input variables for this dataset
      63              : !!  ham_k <type(gs_hamiltonian_type)> = the Hamiltonian H
      64              : !!  mpi_enreg <MPI_type> = MPI-parallelisation information
      65              : !!  nband_k <integer> = number of bands
      66              : !!  npw_k <integer> = number of plane waves
      67              : !!  nspinor <integer> = dimension of spinors
      68              : !!
      69              : !! OUTPUT
      70              : !!  cg <real(npw*nspinor*nband)> = the new cg after application
      71              : !!  of the exponential propagator
      72              : !!  enl <real(bandpp)> = non local contribution to the energy in the
      73              : !!                       NC case - optional
      74              : !!  eig <real(bandpp)> = eigenvalues - optional
      75              : !!
      76              : !! SOURCE
      77        27380 :  subroutine rttddft_exp_taylor(cg,dtset,ham_k,mpi_enreg,nband_k,npw_k,nspinor,enl,eig)
      78              : 
      79              :  !Arguments ------------------------------------
      80              :  !scalars
      81              :  integer,                   intent(in)              :: nband_k
      82              :  integer,                   intent(in)              :: npw_k
      83              :  integer,                   intent(in)              :: nspinor
      84              :  type(dataset_type),        intent(in)              :: dtset
      85              :  type(gs_hamiltonian_type), intent(inout)           :: ham_k
      86              :  type(MPI_type),            intent(inout)           :: mpi_enreg
      87              :  !arrays
      88              :  real(dp), target,          intent(inout)           :: cg(2,npw_k*nband_k*nspinor)
      89              :  real(dp),                  intent(out),   optional :: enl(:)
      90              :  real(dp), pointer,         intent(inout), optional :: eig(:)
      91              : 
      92              :  !Local variables-------------------------------
      93              :  !scalars
      94              :  integer                         :: cpopt
      95              :  integer                         :: iorder
      96              :  integer                         :: nband_t
      97              :  integer                         :: npw_t
      98              :  integer                         :: sij_opt
      99              :  integer                         :: tim_getghc = 5
     100              :  logical                         :: l_paw, l_eig, l_enl
     101              :  real(dp)                        :: dt
     102              :  !arrays
     103        27380 :  integer,            allocatable :: index_wavef_band(:)
     104        27380 :  type(pawcprj_type), allocatable :: cwaveprj(:,:)
     105              :  real(dp), pointer               :: cg_t(:,:) => null()
     106        27380 :  real(dp), target,   allocatable :: cg_trans(:,:)
     107        27380 :  real(dp),           allocatable :: ghc(:,:)
     108        27380 :  real(dp),           allocatable :: gvnlxc_dummy(:,:)
     109        27380 :  real(dp),           allocatable :: gsm1hc(:,:)
     110        27380 :  real(dp),           allocatable :: gsc(:,:)
     111        27380 :  real(dp),           allocatable :: tmp(:,:)
     112              : 
     113              : ! ***********************************************************************
     114              : 
     115              :  !Check what properties we need to compute
     116        27380 :  l_eig = .false.; l_enl = .false.
     117        27380 :  if (present(eig)) then
     118        27260 :     if (associated(eig)) l_eig = .true.
     119              :  end if
     120        27380 :  if (present(enl)) l_enl = (size(enl)>0)
     121              : 
     122              :  !Transpose if paral_kgb
     123        27380 :  if (dtset%paral_kgb == 1 .and. mpi_enreg%nproc_band>1) then
     124         6560 :    call paral_kgb_transpose(cg,cg_trans,mpi_enreg,nband_t,npw_t,nspinor,1,index_wavef_band)
     125         6560 :    cg_t => cg_trans
     126              :  else
     127        20820 :    npw_t = npw_k
     128        20820 :    nband_t = nband_k
     129        20820 :    cg_t => cg
     130              :  end if
     131              : 
     132        27380 :  l_paw = (ham_k%usepaw == 1)
     133        27380 :  if(l_paw) then
     134       724400 :    ABI_MALLOC(cwaveprj, (ham_k%natom,nspinor*nband_t))
     135        27020 :    call pawcprj_alloc(cwaveprj,0,ham_k%dimcprj)
     136              :  else
     137          360 :    ABI_MALLOC(cwaveprj,(0,0))
     138              :  end if
     139        27380 :  cpopt = 0
     140              : 
     141        27380 :  dt = dtset%dtele !electronic timestep
     142              : 
     143        82140 :  ABI_MALLOC(ghc,   (2, npw_t*nspinor*nband_t))
     144        54760 :  ABI_MALLOC(gsc,   (2, npw_t*nspinor*nband_t))
     145        54760 :  ABI_MALLOC(gsm1hc,(2, npw_t*nspinor*nband_t))
     146        27380 :  ABI_MALLOC(gvnlxc_dummy, (0, 0))
     147              : 
     148              :  !*** Taylor expansion ***
     149        54760 :  ABI_MALLOC(tmp,(2, npw_t*nspinor*nband_t))
     150    158948300 :  tmp(:,:) = cg_t(:,:)
     151              : 
     152       136900 :  do iorder = 1, dtset%td_exp_order
     153              : 
     154              :    !** Apply Hamiltonian
     155       109520 :    sij_opt = 0
     156       109520 :    if (iorder == 1 .and. l_eig .and. l_paw) sij_opt = 1
     157       109520 :    if (dtset%paral_kgb /= 1) then
     158              :       call multithreaded_getghc(cpopt,tmp,cwaveprj,ghc,gsc,ham_k,gvnlxc_dummy,1.0_dp, &
     159        83280 :                               & mpi_enreg,nband_t,dtset%prtvol,sij_opt,tim_getghc,0)
     160              :    else
     161              :       call prep_getghc(tmp,ham_k,gvnlxc_dummy,ghc,gsc,1.0_dp,nband_t,mpi_enreg, &
     162        26240 :                      & dtset%prtvol,sij_opt,cpopt,cwaveprj,already_transposed=.true.)
     163              :    end if
     164              : 
     165              :    !** Also apply S^-1 in PAW case
     166       109520 :    if (l_paw) then
     167       108080 :       call apply_invovl(ham_k,ghc,gsm1hc,cwaveprj,npw_t,nband_t,mpi_enreg,nspinor,dtset%invovl_blksliced)
     168    176904080 :       tmp(1,:) =  dt*gsm1hc(2,:)/real(iorder,dp)
     169    176904080 :       tmp(2,:) = -dt*gsm1hc(1,:)/real(iorder,dp)
     170              :    else
     171     35100000 :       tmp(1,:) =  dt*ghc(2,:)/real(iorder,dp)
     172     35100000 :       tmp(2,:) = -dt*ghc(1,:)/real(iorder,dp)
     173              :    end if
     174              : 
     175              :    !** Compute properties if requested
     176       109520 :    if (iorder == 1) then
     177              :       !eigenvalues
     178        27380 :       if (l_eig) then
     179            0 :          if (l_paw) then
     180              :             call rttddft_calc_eig(cg_t,eig,ghc,ham_k%istwf_k,nband_t,npw_t,nspinor, &
     181            0 :                                 & mpi_enreg%me_g0,mpi_enreg%comm_spinorfft,gsc=gsc)
     182              :          else
     183              :             call rttddft_calc_eig(cg_t,eig,ghc,ham_k%istwf_k,nband_t,npw_t,nspinor, &
     184            0 :                                 & mpi_enreg%me_g0,mpi_enreg%comm_spinorfft)
     185              :          end if
     186              :       end if
     187              : 
     188              :       !non local PSP energy contribution in NC case
     189        27380 :       if (l_enl) then
     190          320 :          call rttddft_calc_enl(cg_t,enl,ham_k,nband_t,npw_t,nspinor,mpi_enreg)
     191              :       end if
     192              :    end if
     193              : 
     194              :    !** Update cg
     195    635820580 :    cg_t(:,:) = cg_t(:,:) + tmp(:,:)
     196              : 
     197              :  end do
     198              : 
     199        27380 :  ABI_FREE(tmp)
     200        27380 :  ABI_FREE(ghc)
     201        27380 :  ABI_FREE(gsc)
     202        27380 :  ABI_FREE(gsm1hc)
     203        27380 :  ABI_FREE(gvnlxc_dummy)
     204              : 
     205        27380 :  if(l_paw) call pawcprj_free(cwaveprj)
     206       444980 :  ABI_FREE(cwaveprj)
     207              : 
     208              :  !Transpose back if paral_kgb
     209        27380 :  if (dtset%paral_kgb == 1 .and. mpi_enreg%nproc_band > 1) then
     210         6560 :     call paral_kgb_transpose(cg,cg_trans,mpi_enreg,nband_t,npw_t,nspinor,-1,index_wavef_band)
     211              :  end if
     212              : 
     213        27380 :  nullify(cg_t)
     214              : 
     215        27380 :  end subroutine rttddft_exp_taylor
     216              : !!***
     217              : 
     218              : !!****f* m_rttddft_exponential/paral_kgb_transpose
     219              : !!
     220              : !! NAME
     221              : !!  paral_kgb_transpose
     222              : !!
     223              : !! FUNCTION
     224              : !!  if option = 1: Forward transpose
     225              : !!    Transpose cg_1 in linalg ((npw/npband),nband) distribution
     226              : !!    into cg_2 in fft (npw,bandpp) distribution
     227              : !!
     228              : !!  if option = -1: Backward transpose
     229              : !!    Transpose back cg_2 in fft (npw,bandpp) distribution
     230              : !!    into cg_1 linakg (npw/npband),nband) distribution
     231              : !!
     232              : !! INPUTS
     233              : !!  if option = 1:
     234              : !!    cg_1 <real((npw/nband)*nspinor*nband)>
     235              : !!  if option = -1:
     236              : !!    cg_2 <real(npw*nspinor*bandpp)>
     237              : !!    nband_t <integer> = number of bands after forward transpose (bandpp)
     238              : !!    npw_t <integer> = number of pw after forward transpose (npw_k)
     239              : !!  dtset <type(dataset_type)> = all input variables for this dataset
     240              : !!  mpi_enreg <MPI_type> = MPI-parallelisation information
     241              : !!  nspinor <integer> = "dimension of spinors"
     242              : !!  option <integer> = option for forward or backward transpose
     243              : !!  index_wavef_band <integer> = order of the bands after transpose
     244              : !!
     245              : !! OUTPUT
     246              : !!  if option = 1 :
     247              : !!    cg_2 <real(npw*nspinor*bandpp)>
     248              : !!    nband_t <integer> = number of bands after forward transpose (bandpp)
     249              : !!    npw_t <integer> = number of pw after forward transpose (npw_k)
     250              : !!  if option = -1:
     251              : !!    cg_1 <real((npw/nband)*nspinor*nband)>
     252              : 
     253              : !! SIDE EFFECTS
     254              : !!  if option = 1 :
     255              : !!    cg_2 has been allocated
     256              : !!    index_wavef_band has been allocated
     257              : !!  if option = -1:
     258              : !!    cg_2 has been deallocated
     259              : !!    index_wavef_band has been allocated
     260              : !!
     261              : !! SOURCE
     262        13120 : subroutine paral_kgb_transpose(cg_1,cg_2,mpi_enreg,nband_t,npw_t,nspinor,option,index_wavef_band)
     263              : 
     264              : !Arguments ------------------------------------
     265              : !scalars
     266              : integer,               intent(inout) :: nband_t
     267              : integer,               intent(inout) :: npw_t
     268              : integer,               intent(in)    :: nspinor
     269              : integer,               intent(in)    :: option
     270              : type(MPI_type),        intent(inout) :: mpi_enreg
     271              : !arrays
     272              : integer,  allocatable, intent(inout) :: index_wavef_band(:)
     273              : real(dp),              intent(inout) :: cg_1(:,:)
     274              : real(dp), allocatable, intent(inout) :: cg_2(:,:)
     275              : 
     276              : !Local variables-------------------------------
     277              : !scalars
     278              : integer               :: bandpp
     279              : integer               :: ierr
     280              : integer               :: ikpt_this_proc
     281              : !arrays
     282        26240 : integer               :: recvcountsloc(mpi_enreg%nproc_band)
     283        26240 : integer               :: rdisplsloc(mpi_enreg%nproc_band)
     284        26240 : integer               :: sendcountsloc(mpi_enreg%nproc_band)
     285        26240 : integer               :: sdisplsloc(mpi_enreg%nproc_band)
     286        13120 : real(dp), allocatable :: cg_work(:,:)
     287              : 
     288              : ! ***********************************************************************
     289              : 
     290              :  !Init useful MPI variables
     291        13120 :  bandpp = mpi_enreg%bandpp
     292        13120 :  ikpt_this_proc = bandfft_kpt_get_ikpt()
     293        39360 :  recvcountsloc = bandfft_kpt(ikpt_this_proc)%recvcounts*2*nspinor*bandpp
     294        39360 :  rdisplsloc = bandfft_kpt(ikpt_this_proc)%rdispls*2*nspinor*bandpp
     295        39360 :  sendcountsloc = bandfft_kpt(ikpt_this_proc)%sendcounts*2*nspinor
     296        39360 :  sdisplsloc = bandfft_kpt(ikpt_this_proc)%sdispls*2*nspinor
     297              : 
     298              :  !Forward transpose: cg_1 -> cg_2
     299        13120 :  if (option == 1) then
     300         6560 :    nband_t = bandpp
     301         6560 :    npw_t = bandfft_kpt(ikpt_this_proc)%ndatarecv
     302        19680 :    ABI_MALLOC(cg_2,  (2, npw_t*nspinor*nband_t))
     303        13120 :    ABI_MALLOC(cg_work, (2, npw_t*nspinor*nband_t))
     304              :    !Transpose input cg_1 into cg_work
     305              :    call xmpi_alltoallv(cg_1,sendcountsloc,sdisplsloc,cg_work, &
     306         6560 :                      & recvcountsloc,rdisplsloc,mpi_enreg%comm_band,ierr)
     307              :    !properly sort array according to bandd after alltoall
     308              :    call prep_index_wavef_bandpp(mpi_enreg%nproc_band,mpi_enreg%bandpp,          &
     309              :                               & nspinor,bandfft_kpt(ikpt_this_proc)%ndatarecv , &
     310              :                               & bandfft_kpt(ikpt_this_proc)%recvcounts,         &
     311         6560 :                               & bandfft_kpt(ikpt_this_proc)%rdispls, index_wavef_band)
     312     18759680 :    cg_2(:,:) = cg_work(:,index_wavef_band)
     313         6560 :    ABI_FREE(cg_work)
     314              :  end if
     315              : 
     316              :  !Transpose back: cg_2 -> cg_1
     317        13120 :  if (option == -1) then
     318        19680 :    ABI_MALLOC(cg_work, (2, npw_t*nspinor*nband_t))
     319     18759680 :    cg_work(:,index_wavef_band) = cg_2(:,:)
     320              :    !Transpose cg_work to input cg_1
     321              :    call xmpi_alltoallv(cg_work,recvcountsloc,rdisplsloc,cg_1, &
     322         6560 :                      & sendcountsloc,sdisplsloc,mpi_enreg%comm_band,ierr)
     323              :    !Free memory
     324         6560 :    ABI_FREE(cg_work)
     325         6560 :    ABI_FREE(cg_2)
     326         6560 :    ABI_FREE(index_wavef_band)
     327              :  end if
     328              : 
     329        13120 : end subroutine paral_kgb_transpose
     330              : !!***
     331              : 
     332              : end module m_rttddft_exponential
     333              : !!***
        

Generated by: LCOV version 2.3-1