LCOV - code coverage report
Current view: top level - src/80_rttddft - m_rttddft_properties.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 87.6 % 170 149
Test Date: 2026-09-21 22:40:37 Functions: 87.5 % 8 7

            Line data    Source code
       1              : !!****m* ABINIT/m_rttddft_properties
       2              : !! NAME
       3              : !!  m_rttddft_properties
       4              : !!
       5              : !! FUNCTION
       6              : !!  Contains most of the subroutines to compute
       7              : !!  properties (energy, occupations, eigenvalues..)
       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_properties
      24              : 
      25              :  use defs_basis
      26              :  use defs_abitypes,      only: MPI_type
      27              :  use defs_datatypes,     only: pseudopotential_type
      28              : 
      29              :  use m_bandfft_kpt,      only: bandfft_kpt_type
      30              :  use m_cgprj,            only: ctocprj
      31              :  use m_cgtools,          only: dotprod_g
      32              :  use m_dtfil,            only: datafiles_type
      33              :  use m_dtset,            only: dataset_type
      34              :  use m_energies,         only: energies_type
      35              :  use m_fourier_interpol, only: transgrid
      36              :  use m_hamiltonian,      only: gs_hamiltonian_type
      37              :  use m_mkrho,            only: mkrho
      38              :  use m_nonlop,           only: nonlop
      39              :  use m_pawcprj,          only: pawcprj_type, pawcprj_alloc, pawcprj_get, &
      40              :                              & pawcprj_free, pawcprj_mpi_allgather
      41              :  use m_paw_optics,       only: optics_paw
      42              :  use m_paw_mkrho,        only: pawmkrho
      43              :  use m_paw_occupancies,  only: pawmkrhoij
      44              :  use m_pawrhoij,         only: pawrhoij_type, pawrhoij_free, &
      45              :                              & pawrhoij_alloc, pawrhoij_inquire_dim
      46              :  use m_profiling_abi,    only: abimem_record
      47              :  use m_rttddft_tdks,     only: tdks_type
      48              :  use m_spacepar,         only: meanvalue_g
      49              :  use m_xmpi,             only: xmpi_sum, xmpi_comm_rank
      50              :  use m_dft_energy,       only: entropy
      51              : 
      52              :  implicit none
      53              : 
      54              :  private
      55              : !!***
      56              : 
      57              :  public :: rttddft_calc_density
      58              :  public :: rttddft_calc_etot
      59              :  public :: rttddft_calc_eig
      60              :  public :: rttddft_calc_enl
      61              :  public :: rttddft_calc_kin
      62              :  public :: rttddft_calc_occ
      63              :  public :: rttddft_calc_current
      64              : !!***
      65              : 
      66              : contains
      67              : !!***
      68              : 
      69              : !!****f* m_rttddft_properties/rttddft_calc_density
      70              : !!
      71              : !! NAME
      72              : !!  rttddft_calc_density
      73              : !!
      74              : !! FUNCTION
      75              : !!  Compute electronic density (in 1/bohr^3) from the WF (cg coefficients)
      76              : !!
      77              : !! INPUTS
      78              : !!  dtset <type(dataset_type)> = all input variables for this dataset
      79              : !!  mpi_enreg <MPI_type> = MPI-parallelisation information
      80              : !!  psps <type(pseudopotential_type)> = variables related to pseudopotentials
      81              : !!  tdks <type(tdks_type)> = Main RT-TDDFT object
      82              : !!
      83              : !! OUTPUT
      84              : !!
      85              : !! SOURCE
      86         1805 : subroutine rttddft_calc_density(dtset, mpi_enreg, psps, tdks)
      87              : 
      88              :  !Arguments ------------------------------------
      89              :  !scalars
      90              :  type(tdks_type),            intent(inout) :: tdks
      91              :  type(dataset_type),         intent(in)    :: dtset
      92              :  type(MPI_type),             intent(inout) :: mpi_enreg
      93              :  type(pseudopotential_type), intent(in)    :: psps
      94              : 
      95              :  !Local variables-------------------------------
      96              :  !scalars
      97              :  integer, parameter          :: cplex=1
      98              :  integer                     :: cplex_rhoij
      99              :  integer                     :: ipert, idir
     100              :  integer                     :: my_natom
     101              :  integer                     :: nspden_rhoij
     102              :  integer                     :: tim_mkrho
     103              :  real(dp)                    :: compch_fft
     104              :  !arrays
     105              :  real(dp)                    :: qpt(3)
     106         1805 :  real(dp),allocatable        :: rhowfg(:,:), rhowfr(:,:)
     107         1805 :  type(pawrhoij_type),pointer :: pawrhoij_unsym(:)
     108              :  logical                     :: printout
     109              : 
     110              : ! ***********************************************************************
     111              : 
     112         1805 :  my_natom=mpi_enreg%my_natom
     113              : 
     114         1805 :  tim_mkrho=1
     115              : 
     116         1805 :  printout = (dtset%prtvol /= 0)
     117              : 
     118         1805 :  if (psps%usepaw==1) then
     119              : 
     120         4725 :    ABI_MALLOC(rhowfg,(2,dtset%nfft))
     121         6300 :    ABI_MALLOC(rhowfr,(dtset%nfft,dtset%nspden))
     122              : 
     123              :    ! 1-Compute density from WFs (without compensation charge density nhat)
     124              :    call mkrho(tdks%cg,dtset,tdks%gprimd,tdks%irrzon,tdks%kg,tdks%mcg,mpi_enreg, &
     125              :             & tdks%npwarr,tdks%occ0,tdks%paw_dmft,tdks%phnons,rhowfg,rhowfr,    &
     126              :             & tdks%rprimd,tim_mkrho,tdks%ucvol,tdks%wvl%den,tdks%wvl%wfs,       &
     127         1575 :             & printout=printout)
     128              : 
     129              :    ! 2-Compute cprj = <\psi_{n,k}|p_{i,j}>
     130              :    call ctocprj(tdks%atindx,tdks%cg,1,tdks%cprj,tdks%gmet,tdks%gprimd,0,0,0,           &
     131              :               & dtset%istwfk,tdks%kg,tdks%tdef%kpa,tdks%mcg,tdks%mcprj,dtset%mgfft,    &
     132              :               & dtset%mkmem,mpi_enreg,psps%mpsang,dtset%mpw,dtset%natom,tdks%nattyp,   &
     133              :               & dtset%nband,dtset%natom,dtset%ngfft,dtset%nkpt,dtset%nloalg,           &
     134              :               & tdks%npwarr,dtset%nspinor,dtset%nsppol,dtset%nsppol,psps%ntypat,       &
     135              :               & dtset%paral_kgb,tdks%ph1d,psps,tdks%rmet,dtset%typat,tdks%ucvol,       &
     136         1575 :               & tdks%unpaw,tdks%xred,tdks%ylm,tdks%ylmgr)
     137              : 
     138              :    !paral atom
     139         1575 :    if (my_natom/=dtset%natom) then
     140            0 :      ABI_MALLOC(pawrhoij_unsym,(dtset%natom))
     141              :      call pawrhoij_inquire_dim(cplex_rhoij=cplex_rhoij,nspden_rhoij=nspden_rhoij, &
     142              :                              & nspden=dtset%nspden,spnorb=dtset%pawspnorb,        &
     143            0 :                              & cpxocc=dtset%pawcpxocc)
     144              :      call pawrhoij_alloc(pawrhoij_unsym,cplex_rhoij,nspden_rhoij,dtset%nspinor, &
     145            0 :                        & dtset%nsppol,dtset%typat,pawtab=tdks%pawtab,use_rhoijp=0)
     146              :    else
     147         1575 :        pawrhoij_unsym => tdks%pawrhoij
     148              :    end if
     149              : 
     150              :    ! 3-Compute pawrhoij = \rho_{i,j} = \sum_{n,k}f_{n,k} \tilde{c}^{i,*}_{n,k} \tilde{c}^{j}_{n,k}
     151              :    call pawmkrhoij(tdks%atindx,tdks%atindx1,tdks%cprj,tdks%dimcprj_srt,dtset%istwfk,   &
     152              :                  & dtset%kptopt,dtset%mband,tdks%mband_cprj,tdks%mcprj,dtset%mkmem,    &
     153              :                  & mpi_enreg,dtset%natom,dtset%nband,dtset%nkpt,dtset%nspden,          &
     154              :                  & dtset%nspinor,dtset%nsppol,tdks%occ0,dtset%paral_kgb,tdks%paw_dmft, &
     155         1575 :                  & pawrhoij_unsym,tdks%unpaw,dtset%usewvl,dtset%wtk)
     156              : 
     157              :    ! 4-Symetrize rhoij, compute nhat and add it to rhor
     158              :    ! Note pawrhoij_unsym and pawrhoij are the same, which means that pawrhoij
     159              :    ! cannot be distributed over different atomic sites.
     160         1575 :    ipert=0; idir=0; qpt(:)=zero; compch_fft=-1e-5_dp
     161     24652719 :    tdks%nhat = zero
     162              :    call pawmkrho(1,compch_fft,cplex,tdks%gprimd,idir,tdks%indsym,ipert,mpi_enreg, &
     163              :                & my_natom,dtset%natom,dtset%nspden,dtset%nsym,dtset%ntypat,       &
     164              :                & dtset%paral_kgb,tdks%pawang,tdks%pawfgr,tdks%pawfgrtab,          &
     165              :                & dtset%pawprtvol,tdks%pawrhoij,pawrhoij_unsym,tdks%pawtab,qpt,    &
     166              :                & rhowfg,rhowfr,tdks%rhor,tdks%rprimd,dtset%symafm,tdks%symrec,    &
     167              :                & dtset%typat,tdks%ucvol,dtset%usewvl,tdks%xred,pawnhat=tdks%nhat, &
     168         1575 :                & rhog=tdks%rhog)
     169              : 
     170              :    ! 5-Take care of kinetic energy density
     171         1575 :    if(dtset%usekden==1)then
     172              :      call mkrho(tdks%cg,dtset,tdks%gprimd,tdks%irrzon,tdks%kg,tdks%mcg,mpi_enreg,  &
     173              :               & tdks%npwarr,tdks%occ0,tdks%paw_dmft,tdks%phnons,rhowfg,rhowfr,     &
     174            0 :               & tdks%rprimd,tim_mkrho,tdks%ucvol,tdks%wvl%den,tdks%wvl%wfs,option=1)
     175              : 
     176              :      !FB: Useful?
     177              :      call transgrid(1,mpi_enreg,dtset%nspden,+1,1,1,dtset%paral_kgb,tdks%pawfgr, &
     178            0 :                   & rhowfg,tdks%taug,rhowfr,tdks%taur)
     179              :    end if
     180              : 
     181         1575 :    ABI_FREE(rhowfg)
     182         1575 :    ABI_FREE(rhowfr)
     183              : 
     184         1575 :    if (my_natom/=dtset%natom) then
     185            0 :      call pawrhoij_free(pawrhoij_unsym)
     186            0 :      ABI_FREE(pawrhoij_unsym)
     187              :    else
     188              :       pawrhoij_unsym => NULL()
     189              :    end if
     190              : 
     191              :  else
     192              : 
     193              :    ! 1-Compute density from WFs
     194              :    call mkrho(tdks%cg,dtset,tdks%gprimd,tdks%irrzon,tdks%kg,tdks%mcg,mpi_enreg,    &
     195              :             & tdks%npwarr,tdks%occ0,tdks%paw_dmft,tdks%phnons,tdks%rhog,tdks%rhor, &
     196          230 :             & tdks%rprimd,tim_mkrho,tdks%ucvol,tdks%wvl%den,tdks%wvl%wfs)
     197              :    ! 2-Take care of kinetic energy density
     198          230 :    if(dtset%usekden==1)then
     199              :      call mkrho(tdks%cg,dtset,tdks%gprimd,tdks%irrzon,tdks%kg,tdks%mcg,mpi_enreg,    &
     200              :               & tdks%npwarr,tdks%occ0,tdks%paw_dmft,tdks%phnons,tdks%taug,tdks%taur, &
     201            0 :               & tdks%rprimd,tim_mkrho,tdks%ucvol,tdks%wvl%den,tdks%wvl%wfs,option=1)
     202              :    end if
     203              : 
     204              :  endif
     205              : 
     206         1805 : end subroutine rttddft_calc_density
     207              : !!***
     208              : 
     209              : !!****f* m_rttddft_properties/rttddft_calc_etot
     210              : !!
     211              : !! NAME
     212              : !!  rttddft_calc_energy
     213              : !!
     214              : !! FUNCTION
     215              : !!  Computes total energy
     216              : !!
     217              : !! INPUTS
     218              : !!  dtset <type(dataset_type)> = all input variables for this dataset
     219              : !!  energies <energies_type> = contains the different contribution ot the total energy
     220              : !!  occ <real(nband*nkpt*nsspol)> = occupation numbers at time t
     221              : !!
     222              : !! OUTPUT
     223              : !!  etotal <real(dp)> = the total energy
     224              : !!
     225              : !! SOURCE
     226         1725 : subroutine rttddft_calc_etot(dtset, energies, etotal, occ)
     227              : 
     228              :  !Arguments ------------------------------------
     229              :  !scalars
     230              :  type(dataset_type),  intent(in)    :: dtset
     231              :  type(energies_type), intent(inout) :: energies
     232              :  real(dp),            intent(out)   :: etotal
     233              :  !arrays
     234              :  real(dp),            intent(in)    :: occ(:)
     235              : 
     236              : ! ***********************************************************************
     237              : 
     238              :  ! Compute electronic entropy
     239         1725 :  call rttddft_calc_ent(energies%entropy_ks, dtset, occ)
     240              : 
     241         1725 :  call entropy(dtset,energies)
     242              : 
     243              :  etotal = energies%e_kinetic     &
     244              :       & + energies%e_hartree     &
     245              :       & + energies%e_xc          &
     246              :       & + energies%e_localpsp    &
     247              :       & + energies%e_corepsp     &
     248              :       & + energies%e_ewald       &
     249              :       & + energies%e_vdw_dftd    &
     250              :       & + energies%e_nlpsp_vfock &
     251         1725 :       & + energies%paw%epaw
     252              : !     & + energies%e_entropy
     253              : !FB: @MT Should one add the last e_paw contribution or not?
     254              : !FB: Seeems like all the other contributions are not relevant here @MT?
     255              : !     & + energies%e_chempot     &
     256              : !     & + energies%e_elecfield   &
     257              : !     & + energies%e_magfield    &
     258              : !     & + energies%e_nucdip      &
     259              : !     & + energies%e_hybcomp_E0  &
     260              : !     & - energies%e_hybcomp_v0  &
     261              : !     & + energies%e_hybcomp_v   &
     262              : !     & + energies%e_constrained_dft
     263              : 
     264              : !if (psps%usepaw==0) etotal = etotal + energies%e_nlpsp_vfock - energies%e_fock0
     265              : !if (psps%usepaw==1) etotal = etotal + energies%e_paw + energies%e_fock
     266              : 
     267         1725 : end subroutine rttddft_calc_etot
     268              : !!***
     269              : 
     270              : !!****f* m_rttddft_properties/rttddft_calc_eig
     271              : !!
     272              : !! NAME
     273              : !!  rttddft_calc_eig
     274              : !!
     275              : !! FUNCTION
     276              : !!  Computes eigenvalues from cg and ghc = <G|H|C>
     277              : !!  and gsc = <G|S|C> if paw
     278              : !!
     279              : !! INPUTS
     280              : !!  cg <real(2,npw*nspinor*nband)> = the wavefunction coefficients
     281              : !!  ghc <real(2,npw*nspinor*nband)> = <G|H|C>
     282              : !!  istwf_k <integer> = option describing the storage of wfs at k
     283              : !!  nband <integer> = number of bands
     284              : !!  npw <integer> = number of plane waves
     285              : !!  nspinor <integer> = dimension of spinors
     286              : !!  me_g0 <integer> = if set to 1 current proc contains G(0,0,0)
     287              : !!  comm <integer> = MPI communicator
     288              : !!  gsc <real(2,npw*nspinor*nband)> = <G|S|C> (optional - only in PAW)
     289              : !!
     290              : !! OUTPUT
     291              : !!  eig <real(nband)> = the eigenvalues
     292              : !!
     293              : !! SOURCE
     294            0 : subroutine rttddft_calc_eig(cg,eig,ghc,istwf_k,nband,npw,nspinor,me_g0,comm,gsc)
     295              : 
     296              :  !Arguments ------------------------------------
     297              :  !scalars
     298              :  integer,  intent(in)            :: istwf_k
     299              :  integer,  intent(in)            :: nband
     300              :  integer,  intent(in)            :: npw
     301              :  integer,  intent(in)            :: nspinor
     302              :  integer,  intent(in)            :: me_g0
     303              :  integer,  intent(in)            :: comm
     304              :  !arrays
     305              :  real(dp), intent(in)            :: cg(2,npw*nspinor*nband)
     306              :  real(dp), intent(out)           :: eig(nband)
     307              :  real(dp), intent(in)            :: ghc(2,npw*nspinor*nband)
     308              :  real(dp), intent(in), optional  :: gsc(2,npw*nspinor*nband)
     309              : 
     310              :  !Local variables-------------------------------
     311              :  !scalars
     312              :  integer   :: iband
     313              :  integer   :: shift
     314              :  real(dp)  :: dprod_r, dprod_i
     315              :  !arrays
     316              : 
     317              : ! ***********************************************************************
     318              : 
     319            0 :  do iband=1, nband
     320            0 :     shift = npw*nspinor*(iband-1)
     321              :     !Compute eigenvalues
     322              :     call dotprod_g(eig(iband),dprod_i,istwf_k,npw*nspinor,1, &
     323              :                  & ghc(:, shift+1:shift+npw*nspinor),        &
     324              :                  & cg(:, shift+1:shift+npw*nspinor),         &
     325            0 :                  & me_g0, comm)
     326            0 :     if (present(gsc)) then
     327              :        call dotprod_g(dprod_r,dprod_i,istwf_k,npw*nspinor,1, &
     328              :                     & gsc(:, shift+1:shift+npw*nspinor),     &
     329              :                     & cg(:, shift+1:shift+npw*nspinor),      &
     330            0 :                     & me_g0, comm)
     331            0 :        eig(iband) = eig(iband)/dprod_r
     332              :     end if
     333              :  end do
     334              : 
     335            0 : end subroutine rttddft_calc_eig
     336              : !!***
     337              : 
     338              : !!****f* m_rttddft_properties/rttddft_calc_kin
     339              : !!
     340              : !! NAME
     341              : !!  rttddft_calc_kin
     342              : !!
     343              : !! FUNCTION
     344              : !!  Computes the NL part of energy in NC case
     345              : !!
     346              : !! INPUTS
     347              : !!  cg <real(2,npw*nspinor*nband)> = the wavefunction coefficients
     348              : !!  dtset <type(dataset_type)> = all input variables for this dataset
     349              : !!  ham_k <gs_hamiltonian_type> = hamiltonian at point k
     350              : !!  nband <integer> = number of bands
     351              : !!  npw <integer> = number of plane waves
     352              : !!  nspinor <integer> = dimension of spinors
     353              : !!  occ0 <real(nband)> = initial occupations
     354              : !!  wk <real> = weight of associated kpt
     355              : !!  mpi_enreg <MPI_type> = MPI-parallelisation information
     356              : !!  bandfft_kpt <bandfft_kpt_type> = additional info on parallelisation
     357              : !!   for the associated kpt
     358              : !!
     359              : !! OUTPUT
     360              : !!  kin <real(nband)> = the non local part of the energy in NC case
     361              : !!
     362              : !! SIDE EFFECTS
     363              : !!
     364              : !! SOURCE
     365        27260 : subroutine rttddft_calc_kin(kin,cg,dtset,ham_k,nband,npw,nspinor,occ0,wk,mpi_enreg,bandfft)
     366              : 
     367              :  !Arguments ------------------------------------
     368              :  !scalars
     369              :  integer,                         intent(in)    :: nband
     370              :  integer,                         intent(in)    :: npw
     371              :  integer,                         intent(in)    :: nspinor
     372              :  real(dp),                        intent(in)    :: wk
     373              :  type(dataset_type),              intent(in)    :: dtset
     374              :  type(gs_hamiltonian_type),       intent(in)    :: ham_k
     375              :  type(MPI_type),                  intent(in)    :: mpi_enreg
     376              :  type(bandfft_kpt_type), pointer, intent(in)    :: bandfft
     377              :  !arrays
     378              :  real(dp),                        intent(in)    :: cg(2,npw*nspinor*nband)
     379              :  real(dp),                        intent(inout) :: kin
     380              :  real(dp),                        intent(in)    :: occ0(nband)
     381              : 
     382              :  !Local variables-------------------------------
     383              :  !scalars
     384              :  integer  :: displ
     385              :  integer  :: iband, ipw
     386              :  integer  :: jpw
     387              :  integer  :: me_bandfft
     388              :  integer  :: shift
     389              :  real(dp) :: ar
     390              :  !arrays
     391              : 
     392              : ! ***********************************************************************
     393              : 
     394        27260 :  if (dtset%paral_kgb /= 1) then
     395              :    displ = 0
     396              :  else
     397         6560 :    me_bandfft = xmpi_comm_rank(mpi_enreg%comm_bandspinorfft)
     398         6560 :    displ = bandfft%rdispls(me_bandfft+1)
     399              :  end if
     400              : 
     401       255900 :  do iband=1, nband
     402       255900 :    if (abs(occ0(iband))>tol8) then
     403       115400 :       shift = npw*nspinor*(iband-1)
     404              :       !FB: meanvalue_g does the mpi_sum over the bands inside, that's not very efficient since
     405              :       !FB: we could do it only once at the end
     406              :       !FB: From Lucas: meanvalue_g seems slow
     407              :       !FB: It maybe useful not to use meanvalue_g at all here
     408              :       !call meanvalue_g(ar,ham_k%kinpw_k(1+displ:displ+npw*nspinor),0,1,mpi_enreg,npw,nspinor, &
     409              :       !               & cg(:,1+shift:shift+npw*nspinor),cg(:,1+shift:shift+npw*nspinor),0)
     410       115400 :       ar = zero
     411     24625780 :       do ipw = 1, npw
     412     24625780 :          ar = ar + ham_k%kinpw_k(displ+ipw)*(cg(1,shift+ipw)*cg(1,shift+ipw)+cg(2,shift+ipw)*cg(2,shift+ipw))
     413              :       end do
     414       115400 :       if(nspinor==2)then
     415            0 :          do ipw = 1+npw, 2*npw
     416            0 :             jpw = ipw - npw
     417            0 :             ar = ar + ham_k%kinpw_k(displ+jpw)*(cg(1,shift+ipw)*cg(1,shift+ipw)+cg(2,shift+ipw)*cg(2,shift+ipw))
     418              :          end do
     419              :       end if
     420       115400 :       kin = kin + wk*occ0(iband)*ar
     421              :    end if
     422              :  end do
     423              : 
     424        27260 : end subroutine rttddft_calc_kin
     425              : !!***
     426              : 
     427              : !!****f* m_rttddft_properties/rttddft_calc_enl
     428              : !!
     429              : !! NAME
     430              : !!  rttddft_calc_enl
     431              : !!
     432              : !! FUNCTION
     433              : !!  Computes the NL part of energy in NC case
     434              : !!
     435              : !! INPUTS
     436              : !!  cg <real(2,npw*nspinor*nband)> = the wavefunction coefficients
     437              : !!  ham_k <gs_hamiltonian_type> = hamiltonian at point k
     438              : !!  nband <integer> = number of bands
     439              : !!  npw <integer> = number of plane waves
     440              : !!  nspinor <integer> = dimension of spinors
     441              : !!  mpi_enreg <MPI_type> = MPI-parallelisation information
     442              : !!
     443              : !! OUTPUT
     444              : !!  enl <real(nband)> = the non local part of the energy in NC case
     445              : !!
     446              : !! SIDE EFFECTS
     447              : !!
     448              : !! SOURCE
     449          320 : subroutine rttddft_calc_enl(cg,enl,ham_k,nband,npw,nspinor,mpi_enreg)
     450              : 
     451              :  !Arguments ------------------------------------
     452              :  !scalars
     453              :  integer,                   intent(in)    :: nband
     454              :  integer,                   intent(in)    :: npw
     455              :  integer,                   intent(in)    :: nspinor
     456              :  type(gs_hamiltonian_type), intent(in)    :: ham_k
     457              :  type(MPI_type),            intent(in)    :: mpi_enreg
     458              :  !arrays
     459              :  real(dp),                  intent(inout) :: cg(2,npw*nspinor*nband)
     460              :  real(dp),                  intent(out)   :: enl(nband)
     461              : 
     462              :  !Local variables-------------------------------
     463              :  !scalars
     464              :  integer, parameter              :: choice=1
     465              :  integer, parameter              :: cpopt=-1
     466              :  integer, parameter              :: paw_opt=0
     467              :  integer, parameter              :: signs=1
     468              :  integer, parameter              :: tim_getghc = 5
     469              :  !arrays
     470          320 :  type(pawcprj_type), allocatable :: cprj_dummy(:,:)
     471          320 :  real(dp),           allocatable :: eig_dummy(:)
     472          320 :  real(dp),           allocatable :: gvnlxc_dummy(:,:)
     473          320 :  real(dp),           allocatable :: gsc_dummy(:,:)
     474              : ! ***********************************************************************
     475              : 
     476          640 :  ABI_MALLOC(cprj_dummy,(ham_k%natom,0))
     477          320 :  ABI_MALLOC(gsc_dummy,(0,0))
     478          320 :  ABI_MALLOC(gvnlxc_dummy, (0, 0))
     479          960 :  ABI_MALLOC(eig_dummy,(nband))
     480              :  call nonlop(choice,cpopt,cprj_dummy,enl,ham_k,0,eig_dummy,mpi_enreg,nband, &
     481          320 :             & 1,paw_opt,signs,gsc_dummy,tim_getghc,cg,gvnlxc_dummy)
     482          320 :  ABI_FREE(cprj_dummy)
     483          320 :  ABI_FREE(gsc_dummy)
     484          320 :  ABI_FREE(eig_dummy)
     485          320 :  ABI_FREE(gvnlxc_dummy)
     486              : 
     487          320 : end subroutine rttddft_calc_enl
     488              : !!***
     489              : 
     490              : !!****f* m_rttddft_properties/rttddft_calc_occ
     491              : !!
     492              : !! NAME
     493              : !!  rttddft_calc_occ
     494              : !!
     495              : !! FUNCTION
     496              : !!  Computes occupations at time t from cg(t), cg0 and occ0
     497              : !!  In NC:
     498              : !!    f_{n,k}(t) = \sum_{m} f_{m,k}(0) <\psi_m(0)|\psi_n(t)>
     499              : !!  In PAW:
     500              : !!    f_{n,k}(t) = \sum_{m} f_{m,k}(0) <\psi_m(0)|S|\psi_n(t)>
     501              : !!               = \sum_{m} f_{m,k}(0) [ <\psi_m(0)|\psi_n(t)> +
     502              : !!                 \sum_{i} <\psi_m(0)|p_{i}>\sum_jS_{i,j}<p_{j}|\psi_n(t)> ]
     503              : !!
     504              : !! INPUTS
     505              : !!  cg <real(2,npw*nspinor*nband)> = the wavefunction coefficients
     506              : !!  cg0 <real(2,npw*nspinor*nband)> = the initial wavefunction coefficients
     507              : !!  dtset <type(dataset_type)> = all input variables for this dataset
     508              : !!  ham_k <gs_hamiltonian_type> = hamiltonian at point k
     509              : !!  ikpt <integer> = indice of the considered k-point
     510              : !!  ibg <integer> = indice of the considered k-point for cprj
     511              : !!  isppol <integer> = indice of the considered spin-polarization
     512              : !!  mpi_enreg <MPI_type> = MPI-parallelisation information
     513              : !!  nband_k <integer> = number of bands
     514              : !!  npw_k <integer> = number of plane waves
     515              : !!  nspinor <integer> = dimension of spinors
     516              : !!  occ0 <real(nband)> = initial occupations
     517              : !!  tdks <type(tdks_type)> = Main RT-TDDFT object
     518              : !!
     519              : !! OUTPUT
     520              : !!  occ <real(nband)> = the occupations at time t
     521              : !!
     522              : !! SOURCE
     523        27260 : subroutine rttddft_calc_occ(cg,cg0,dtset,ham_k,ikpt,ibg,isppol,mpi_enreg,nband_k,npw_k,nspinor,occ,occ0,tdks)
     524              : 
     525              :  !Arguments ------------------------------------
     526              :  !scalars
     527              :  integer,                   intent(in)    :: ikpt
     528              :  integer,                   intent(in)    :: ibg
     529              :  integer,                   intent(in)    :: isppol
     530              :  integer,                   intent(in)    :: nband_k
     531              :  integer,                   intent(in)    :: npw_k
     532              :  integer,                   intent(in)    :: nspinor
     533              :  type(dataset_type),        intent(in)    :: dtset
     534              :  type(gs_hamiltonian_type), intent(in)    :: ham_k
     535              :  type(MPI_type),            intent(in)    :: mpi_enreg
     536              :  type(tdks_type), target,   intent(in)    :: tdks
     537              :  !arrays
     538              :  real(dp),                  intent(inout) :: cg(2,npw_k*nspinor*nband_k)
     539              :  real(dp),                  intent(in)    :: cg0(2,npw_k*nspinor*nband_k)
     540              :  real(dp),                  intent(out)   :: occ(nband_k)
     541              :  real(dp),                  intent(in)    :: occ0(nband_k)
     542              : 
     543              :  !Local variables-------------------------------
     544              :  !scalars
     545              :  integer                     :: iband, jband, ierr, ind
     546              :  integer                     :: nband_cprj_k
     547              :  integer                     :: natom
     548              :  integer                     :: shift
     549              :  !parameters for nonlop
     550              :  integer, parameter          :: cpopt = 2
     551              :  integer, parameter          :: choice = 1
     552              :  integer, parameter          :: idir = 1
     553              :  integer, parameter          :: nnlout = 1
     554              :  integer, parameter          :: paw_opt = 3
     555              :  integer, parameter          :: signs = 1
     556              :  integer, parameter          :: tim_nonlop = 16
     557              :  logical                     :: cprj_paral_band
     558              :  !arrays
     559        54520 :  real(dp)                    :: csc(2*nband_k)
     560        27260 :  real(dp),allocatable        :: gsc(:,:),gvnlxc(:,:)
     561        27260 :  real(dp),allocatable        :: enlout(:),enlout_im(:)
     562        27260 :  type(pawcprj_type), pointer :: cprj(:,:), cprj_k(:,:)
     563        27260 :  type(pawcprj_type), pointer :: cprj0(:,:), cprj0_k(:,:)
     564              : 
     565              : ! ***********************************************************************
     566              : 
     567              :  !Prepare cprj in PAW case
     568        27260 :  cprj_paral_band=.false.
     569        27260 :  if (ham_k%usepaw == 1) then
     570              :     ! Determine if cprj datastructure is distributed over bands
     571        26940 :     cprj_paral_band=(tdks%mband_cprj<dtset%mband)
     572        26940 :     nband_cprj_k=nband_k; if (cprj_paral_band) nband_cprj_k=mpi_enreg%bandpp
     573        26940 :     natom = dtset%natom
     574              :     ! Extract the right cprj for this k-point
     575        26940 :     if (dtset%mkmem*dtset%nsppol/=1) then
     576       707280 :        ABI_MALLOC(cprj_k,(natom,nspinor*nband_cprj_k))
     577       680340 :        ABI_MALLOC(cprj0_k,(natom,nspinor*nband_cprj_k))
     578        26940 :        call pawcprj_alloc(cprj_k,0,tdks%dimcprj)
     579        26940 :        call pawcprj_alloc(cprj0_k,0,tdks%dimcprj)
     580              :        call pawcprj_get(tdks%atindx1,cprj_k,tdks%cprj,natom,1,ibg,ikpt,0,isppol,     &
     581              :                       & tdks%mband_cprj,dtset%mkmem,natom,nband_cprj_k,nband_cprj_k, &
     582              :                       & nspinor,dtset%nsppol,tdks%unpaw,mpicomm=mpi_enreg%comm_kpt,  &
     583        26940 :                       & proc_distrb=mpi_enreg%proc_distrb)
     584              :        call pawcprj_get(tdks%atindx1,cprj0_k,tdks%cprj0,natom,1,ibg,ikpt,0,isppol,   &
     585              :                       & tdks%mband_cprj,dtset%mkmem,natom,nband_cprj_k,nband_cprj_k, &
     586              :                       & nspinor,dtset%nsppol,tdks%unpaw,mpicomm=mpi_enreg%comm_kpt,  &
     587        26940 :                       & proc_distrb=mpi_enreg%proc_distrb)
     588              :     else
     589            0 :        cprj_k => tdks%cprj
     590            0 :        cprj0_k => tdks%cprj0
     591              :     end if
     592              :     ! If cprj are distributed over bands, gather them (because we need to mix bands)
     593        26940 :     if (cprj_paral_band) then
     594       179200 :        ABI_MALLOC(cprj,(natom,nspinor*nband_k))
     595       172800 :        ABI_MALLOC(cprj0,(natom,nspinor*nband_k))
     596         6400 :        call pawcprj_alloc(cprj,0,tdks%dimcprj)
     597         6400 :        call pawcprj_alloc(cprj0,0,tdks%dimcprj)
     598              :        call pawcprj_mpi_allgather(cprj_k,cprj,natom,nspinor*nband_cprj_k,mpi_enreg%bandpp, &
     599              :                                 & tdks%dimcprj,0,mpi_enreg%nproc_band,mpi_enreg%comm_band, &
     600         6400 :                                 & ierr,rank_ordered=.false.)
     601              :        call pawcprj_mpi_allgather(cprj0_k,cprj0,natom,nspinor*nband_cprj_k,mpi_enreg%bandpp, &
     602              :                                 & tdks%dimcprj,0,mpi_enreg%nproc_band,mpi_enreg%comm_band,   &
     603         6400 :                                 & ierr,rank_ordered=.false.)
     604              :     else
     605        20540 :        cprj => cprj_k
     606        20540 :        cprj0 => cprj0_k
     607              :     end if
     608              : 
     609              :    !allocate necessary arrays for nonlop
     610        26940 :    ABI_MALLOC(gsc,(0,0))
     611        26940 :    ABI_MALLOC(gvnlxc,(0,0))
     612        80820 :    ABI_MALLOC(enlout,(nband_k))
     613        53880 :    ABI_MALLOC(enlout_im,(nband_k))
     614              :  end if
     615              : 
     616       484540 :  csc = zero
     617       255900 :  do iband = 1, nband_k
     618              :    !* 1 - Compute csc = <cg0|cg>
     619       228640 :    shift = npw_k*nspinor*(iband-1)
     620              :    call zgemv('C',npw_k*nspinor,nband_k,cone,cg0,npw_k*nspinor, &
     621       228640 :             & cg(:,shift+1:shift+npw_k*nspinor),1,czero,csc,1)
     622              :    !If band parallel then reduce csc
     623       228640 :    if (mpi_enreg%nproc_band > 1) then
     624        55040 :       call xmpi_sum(csc,mpi_enreg%comm_bandfft,ierr)
     625              :    end if
     626              :    !* 2 - If PAW, add the additional term \sum_i cprj_i \sum_j S_{i,j} cprj_j
     627       228640 :    if (ham_k%usepaw == 1) then
     628              :       call nonlop(choice,cpopt,cprj(:,iband:iband+(nspinor-1)),enlout,     &
     629              :                 & ham_k,idir,(/zero/),mpi_enreg,1,nnlout,paw_opt,signs,    &
     630              :                 & gsc,tim_nonlop,cg(:,shift+1:shift+npw_k*nspinor),gvnlxc, &
     631       220960 :                 & cprjin_left=cprj0,enlout_im=enlout_im,ndat_left=nband_k)
     632      2217120 :       do jband = 1, nband_k
     633      1996160 :          csc(2*jband-1) = csc(2*jband-1) + enlout(jband)
     634      2217120 :          csc(2*jband)   = csc(2*jband)   + enlout_im(jband)
     635              :       end do
     636              :    end if
     637              :    !* 3 - Calc occupations from csc and occ0
     638      2436380 :    do jband = 1, nband_k
     639      2180480 :       ind = 2*jband
     640      2409120 :       occ(iband) = occ(iband) + occ0(jband)*(csc(ind-1)**2+csc(ind)**2)
     641              :    end do
     642              :  end do
     643              : 
     644        27260 :  if (ham_k%usepaw == 1) then
     645        26940 :    ABI_FREE(gsc)
     646        26940 :    ABI_FREE(gvnlxc)
     647        26940 :    ABI_FREE(enlout)
     648        26940 :    ABI_FREE(enlout_im)
     649        26940 :    if (cprj_paral_band) then
     650         6400 :       call pawcprj_free(cprj)
     651         6400 :       ABI_FREE(cprj)
     652         6400 :       call pawcprj_free(cprj0)
     653         6400 :       ABI_FREE(cprj0)
     654              :    end if
     655        26940 :    if (dtset%mkmem*dtset%nsppol/=1) then
     656        26940 :       call pawcprj_free(cprj_k)
     657        26940 :       ABI_FREE(cprj_k)
     658        26940 :       call pawcprj_free(cprj0_k)
     659        26940 :       ABI_FREE(cprj0_k)
     660              :    end if
     661              :  end if
     662              : 
     663        54520 : end subroutine rttddft_calc_occ
     664              : !!***
     665              : 
     666              : !!****f* m_rttddft_properties/rttddft_calc_ent
     667              : !!
     668              : !! NAME
     669              : !!  rttddft_calc_ent
     670              : !!
     671              : !! FUNCTION
     672              : !!  Computes electronic entropy from occupation numbers f_{nk}
     673              : !!  S = -2 \sum_k \sum_n w(k) [ f_{nk}*ln(f_{nk}) + (1-f_{nk})*ln(1-f_{nk}) ]
     674              : !!
     675              : !! INPUTS
     676              : !!  dtset <type(dataset_type)> = all input variables for this dataset
     677              : !!  occ <real(nband*nkpt*nsspol)> = occupation numbers at time t
     678              : !!
     679              : !! OUTPUT
     680              : !!  entropy <real>
     681              : !!
     682              : !! SOURCE
     683         1725 : subroutine rttddft_calc_ent(entropy,dtset,occ)
     684              : 
     685              :  !Arguments ------------------------------------
     686              :  !scalars
     687              :  real(dp),           intent(out) :: entropy
     688              :  type(dataset_type), intent(in)  :: dtset
     689              :  !arrays
     690              :  real(dp),           intent(in)  :: occ(:)
     691              : 
     692              :  !Local variables-------------------------------
     693              :  !scalars
     694              :  integer  :: band_index
     695              :  integer  :: iband, isppol, ikpt
     696              :  integer  :: nband_k
     697              :  real(dp) :: fnk
     698              : 
     699              : ! ***********************************************************************
     700              : 
     701         1725 :  entropy = zero
     702         1725 :  band_index=0
     703              : 
     704         3450 :  do isppol = 1, dtset%nsppol
     705        50390 :    do ikpt = 1, dtset%nkpt
     706        46940 :       nband_k = dtset%nband(ikpt+(isppol-1)*dtset%nkpt)
     707       440700 :       do iband = 1, nband_k
     708       393760 :          fnk = occ(iband+band_index)*0.5_dp
     709       440700 :          if( fnk>tol16 .and. (one-fnk)>tol16 ) then
     710       352957 :             entropy = entropy - two*dtset%wtk(ikpt)*(fnk*log(fnk)+(one-fnk)*log(one-fnk))
     711              :          end if
     712              :       end do
     713        48665 :       band_index = band_index + nband_k
     714              :    end do
     715              :  end do
     716              : 
     717         1725 : end subroutine rttddft_calc_ent
     718              : !!***
     719              : 
     720              : !!****f* m_rttddft_properties/rttddft_calc_current
     721              : !!
     722              : !! NAME
     723              : !!  rttddft_calc_current
     724              : !!
     725              : !! FUNCTION
     726              : !!  Computes macroscopic current density
     727              : !!  In NC:
     728              : !!    J(t) = -1/Omega Im[\sum_{n,k} f_{nk}(0) <\tilde{psi}_{nk}|\nabla|\tilde{psi}_{nk}>]  - A N_v/Omega
     729              : !!           + Gauge-dependent terms?
     730              : !!  In PAW:
     731              : !!    J(t) = -1/Omega Im[ \sum_{n,k} f_{nk}(0) <\tilde{psi}_{nk}|\nabla|\tilde{psi}_{nk}> +
     732              : !!                        \sum_{aij} \rho_{aij} <\phi_{aij}|\nabla|\phi_{aij}> -
     733              : !!                        \sum_{aij} \rho_{aij} <\tilde{\phi}_{aij}|\nabla|\tilde{\phi}_{aij}> ]
     734              : !!           - A/Omega \int \tilde{n}(r,t)dr
     735              : !! INPUTS
     736              : !!  tdks <type(tdks_type)> = Main RT-TDDFT object
     737              : !!  dtset <type(dataset_type)> = all input variables for this dataset
     738              : !!  mpi_enreg <MPI_type> = MPI-parallelisation information
     739              : !!
     740              : !! OUTPUT
     741              : !!  current = the macroscopic current
     742              : !!
     743              : !! NOTES
     744              : !!  Im[<\tilde{psi}_{nk}|\nabla|\tilde{psi}_{nk}>] = <\tilde{psi}_{nk}|-i\nabla|\tilde{psi}_{nk}>
     745              : !!
     746              : !! SOURCE
     747         1121 : subroutine rttddft_calc_current(tdks, dtset, dtfil, psps, mpi_enreg)
     748              : 
     749              :  !Arguments ------------------------------------
     750              :  !scalars
     751              :  type(tdks_type), target,    intent(inout) :: tdks
     752              :  type(dataset_type),         intent(in)    :: dtset
     753              :  type(datafiles_type),       intent(in)    :: dtfil
     754              :  type(pseudopotential_type), intent(in)    :: psps
     755              :  type(MPI_type),             intent(in)    :: mpi_enreg
     756              : 
     757              :  !Local variables-------------------------------
     758              :  !scalars
     759              :  integer  :: iband, ikpt, isppol, bdtot_index, nband_k
     760              :  real(dp) :: current_k(3)
     761              :  !arrays
     762         2242 :  real(dp), target :: psinablapsi(2,3,dtset%mband,dtset%nkpt)
     763              : 
     764              : ! ***********************************************************************
     765              : 
     766         1121 :  if (psps%usepaw==1) then
     767              :    ! 1 - Computes <\psi_{nk}|v|\psi_{nk}> = <\psi_{nk}|-i\nabla|\psi_{nk}> = Im[<\tilde{psi}_{nk}|\nabla|\tilde{psi}_{nk}>]
     768              :    call optics_paw(tdks%atindx1,tdks%cg,tdks%cprj,tdks%dimcprj,dtfil,dtset,tdks%eigen,tdks%gprimd,tdks%hdr, &
     769              :                  & tdks%kg,dtset%mband,tdks%mcg,tdks%mcprj,dtset%mkmem,mpi_enreg,psps%mpsang,dtset%mpw,     &
     770              :                  & dtset%natom,dtset%nkpt,tdks%npwarr,dtset%nsppol,tdks%pawang,tdks%pawrad,tdks%pawrhoij,   &
     771         1121 :                  & tdks%pawtab,dtset%znucl,psinablapsi)
     772              : 
     773              :    ! 2 - Sum over bands and k-points
     774         5605 :    tdks%current = 0.0_dp
     775         1121 :    bdtot_index=0
     776              :    !Loop over spins
     777         2242 :    do isppol=1, dtset%nsppol
     778              :       !Loop over kpoints
     779        36993 :       do ikpt = 1, dtset%nkpt
     780        35872 :          current_k = 0.0_dp
     781        35872 :          nband_k=dtset%nband(ikpt+(isppol-1)*dtset%nkpt)
     782       322848 :          do iband = 1, nband_k
     783       286976 :             current_k(1) = current_k(1) + tdks%occ0(bdtot_index+iband)*psinablapsi(1,1,iband,ikpt)
     784       286976 :             current_k(2) = current_k(2) + tdks%occ0(bdtot_index+iband)*psinablapsi(1,2,iband,ikpt)
     785       322848 :             current_k(3) = current_k(3) + tdks%occ0(bdtot_index+iband)*psinablapsi(1,3,iband,ikpt)
     786              :          end do
     787       143488 :          tdks%current(:,isppol) = tdks%current(:,isppol) + dtset%wtk(ikpt)*current_k(:)
     788        36993 :          bdtot_index = bdtot_index + nband_k
     789              :       end do !nkpt
     790              : 
     791              :       ! 3 - Add last contribution from vector potential times integral of the density
     792              :       tdks%current(:,isppol) = tdks%current(:,isppol) + &
     793     16092947 :                              & tdks%tdef%vecpot(:)*sum(tdks%rhor(:,isppol)-tdks%nhat(:,isppol))*tdks%ucvol/tdks%nfftf
     794              : 
     795         5605 :       tdks%current(:,isppol) = -tdks%current(:,isppol)/tdks%ucvol
     796              : 
     797              :    end do !nsspol
     798              : 
     799              :  end if
     800              : 
     801         1121 : end subroutine rttddft_calc_current
     802              : !!***
     803              : 
     804              : end module m_rttddft_properties
     805              : !!***
        

Generated by: LCOV version 2.3-1