LCOV - code coverage report
Current view: top level - src/80_rttddft - m_rttddft_tdef.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 87.9 % 58 51
Test Date: 2026-11-11 19:49:02 Functions: 60.0 % 5 3
Branches: 54.5 % 156 85

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_rttddft_tdef
       2                 :             : !! NAME
       3                 :             : !!  m_rttddft_tdef
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!  Contains definition of the tdef type
       7                 :             : !!  related to time-dependent electric field
       8                 :             : !!
       9                 :             : !! COPYRIGHT
      10                 :             : !!  Copyright (C) 2021-2026 ABINIT group (FBrieuc)
      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_tdef
      24                 :             : 
      25                 :             :  use defs_basis
      26                 :             :  use defs_abitypes,   only: MPI_type
      27                 :             : 
      28                 :             :  use m_dtset,         only: dataset_type
      29                 :             :  use m_errors,        only: msg_hndl
      30                 :             :  use m_initylmg,      only: initylmg
      31                 :             :  use m_profiling_abi, only: abimem_record
      32                 :             :  use m_xmpi,          only: xmpi_bcast
      33                 :             : 
      34                 :             :  implicit none
      35                 :             : 
      36                 :             :  private
      37                 :             : !!***
      38                 :             : 
      39                 :             : !! NAME
      40                 :             : !! tdef_type: Time Dependent Electric Field type
      41                 :             : !! Object containing the TD Electric field
      42                 :             : !! for RT-TDDFT runs
      43                 :             : !!
      44                 :             : !! SOURCE
      45                 :             :  type,public :: tdef_type
      46                 :             : 
      47                 :             :    integer  :: ef_type       !type of TD electric feld (Dirac or sin^2 pulse)
      48                 :             :    real(dp) :: efield(3)     !TD external elec. field perturbation
      49                 :             :    real(dp) :: ef_ezero(3)   !E_0 = |E_0|*polarization
      50                 :             :    real(dp) :: vecpot(3)     !total vector potential
      51                 :             :    real(dp) :: vecpot_ext(3) !external vector potential
      52                 :             :    real(dp) :: vecpot_ind(3,2) !induced vector potential at t and t-dt
      53                 :             :    real(dp) :: vecpot_red(3) !total vector potential in reduced coord. (in reciprocal space)
      54                 :             :    real(dp) :: ef_tzero      !time at which elec field is switched on
      55                 :             :    real(dp) :: ef_omega      !angular freq. of TD elec field
      56                 :             :    real(dp) :: ef_tau        !time width of the pulse
      57                 :             :    real(dp) :: ef_sin_a      !useful constant for sin^2 pulse
      58                 :             :    real(dp) :: ef_sin_b      !useful constant for sin^2 pulse
      59                 :             :    real(dp), allocatable :: kpa(:,:) ! contains kpts + A
      60                 :             :                                      ! (in reduced coordinates in reciprocal space)
      61                 :             :    logical  :: induced_vecpot ! Add the vector potential induced by the current density
      62                 :             :                               ! in the Hamiltonian
      63                 :             : 
      64                 :             :    contains
      65                 :             : 
      66                 :             :    procedure :: init => tdef_init
      67                 :             :    procedure :: update => tdef_update
      68                 :             :    procedure :: restart => tdef_restart
      69                 :             : 
      70                 :             :  end type tdef_type
      71                 :             : !!***
      72                 :             : 
      73                 :             : contains
      74                 :             : !!***
      75                 :             : 
      76                 :             : !!****f* m_rttddft/tdef_init
      77                 :             : !!
      78                 :             : !! NAME
      79                 :             : !!  tdef_init
      80                 :             : !!
      81                 :             : !! FUNCTION
      82                 :             : !!  Update value of electric field and vector potential at time t
      83                 :             : !!
      84                 :             : !! INPUTS
      85                 :             : !!  [tdef = tdef structure to update]
      86                 :             : !!  td_ef_type = type of electric field (Dirac or sin^2 pulse)
      87                 :             : !!  td_ef_pol = polarization
      88                 :             : !!  td_ef_ezero = Amplitude (E_0 = |E_0|*polarization)
      89                 :             : !!  td_ef_tzero = time at which the pulse is switched on
      90                 :             : !!  td_ef_lambda = wavelength (for sin^2 pulse)
      91                 :             : !!  td_ef_tau = time width of the pulse (for finite-width delta kick or sin^2 pulse)
      92                 :             : !!  time = propagation time
      93                 :             : !!  nkpt = number of kpoints
      94                 :             : !!  kpts = kpoints array
      95                 :             : !!
      96                 :             : !! OUTPUT
      97                 :             : !!  [tdef = updated tdef structure]
      98                 :             : !!
      99                 :             : !! SOURCE
     100         [ -  + ]:          50 : subroutine tdef_init(tdef,td_ef_type,td_ef_pol,td_ef_ezero,td_ef_tzero,td_ef_lambda,td_ef_tau,td_ef_induced_vecpot,nkpt,kpts)
     101                 :             : 
     102                 :             :  !Arguments ------------------------------------
     103                 :             :  !scalars
     104                 :             :  class(tdef_type), intent(inout) :: tdef
     105                 :             :  integer,          intent(in)    :: td_ef_type, td_ef_induced_vecpot, nkpt
     106                 :             :  real(dp),         intent(in)    :: td_ef_ezero, td_ef_tzero, td_ef_lambda, td_ef_tau
     107                 :             :  !arrays
     108                 :             :  real(dp),         intent(in)    :: kpts(:,:)
     109                 :             : 
     110                 :             :  !Local variables-------------------------------
     111                 :             :  real(dp),         intent(in)    :: td_ef_pol(3)
     112                 :             : 
     113                 :             : ! ***********************************************************************
     114                 :             : 
     115         [ -  + ]:          50 :  if (td_ef_type > 1 .or. td_ef_type < 0) then
     116                 :           0 :    ABI_ERROR("Wrong value of td_ef_type")
     117                 :             :  end if
     118                 :             : 
     119                 :          50 :  tdef%ef_type  = td_ef_type
     120         [ +  + ]:         200 :  tdef%ef_ezero = td_ef_pol*td_ef_ezero
     121                 :          50 :  tdef%ef_tau   = td_ef_tau
     122                 :          50 :  tdef%ef_omega = 2.0_dp*pi*Speed_Light/td_ef_lambda !2*pi*f=2*pi*c/lambda
     123                 :          50 :  tdef%ef_tzero = td_ef_tzero
     124                 :          50 :  tdef%ef_sin_a = 2.0_dp*pi/td_ef_tau + tdef%ef_omega
     125                 :          50 :  tdef%ef_sin_b = 2.0_dp*pi/td_ef_tau - tdef%ef_omega
     126         [ +  + ]:          50 :  if (td_ef_induced_vecpot == 0) then
     127                 :          48 :    tdef%induced_vecpot = .false.
     128         [ +  - ]:           2 :  else if (td_ef_induced_vecpot == 1) then
     129                 :           2 :    tdef%induced_vecpot = .true.
     130                 :             :  else
     131                 :           0 :     ABI_ERROR("Wrong value of td_ef_induced_vecpot")
     132                 :             :  end if
     133                 :             : 
     134         [ +  + ]:         200 :  tdef%efield = zero
     135         [ +  + ]:         200 :  tdef%vecpot = zero
     136         [ +  + ]:         200 :  tdef%vecpot_ext = zero
     137   [ +  +  +  + ]:         450 :  tdef%vecpot_ind = zero
     138         [ +  + ]:         200 :  tdef%vecpot_red = zero
     139                 :             : 
     140   [ -  +  +  -  :         150 :  ABI_MALLOC(tdef%kpa,(3,nkpt))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     141   [ +  -  +  -  :        3732 :  tdef%kpa = kpts
          -  +  -  -  +  
                +  +  + ]
     142                 :             : 
     143                 :          50 : end subroutine tdef_init
     144                 :             : !!***
     145                 :             : 
     146                 :             : !!****f* m_rttddft/tdef_update
     147                 :             : !!
     148                 :             : !! NAME
     149                 :             : !!  tdef_update
     150                 :             : !!
     151                 :             : !! FUNCTION
     152                 :             : !!  Update value of electric field and vector potential at time t
     153                 :             : !!
     154                 :             : !! INPUTS
     155                 :             : !!  [tdef = tdef structure to update]
     156                 :             : !!  dtset = dataset structure
     157                 :             : !!  mpi_enreg = MPI communicators structure
     158                 :             : !!  time = propagation time
     159                 :             : !!  rprimd = cell vectors (direct space)
     160                 :             : !!  gprimd = cell vectors (reciprocal space)
     161                 :             : !!  kg = kpoints in reciprocal space
     162                 :             : !!  mpsang = 1+maximum angular momentum for nonlocal pseudopotential (required by initylmg)
     163                 :             : !!  npwarr = array holding npw for each k point
     164                 :             : !!  ylm = real spherical harmonics for each G and k point
     165                 :             : !!  ylmgr = gradient of real spherical harmonics for each G and k point
     166                 :             : !!  current = total current density
     167                 :             : !!
     168                 :             : !! OUTPUT
     169                 :             : !!  [tdef = updated tdef structure]
     170                 :             : !!
     171                 :             : !! SOURCE
     172   [ -  +  -  +  :        1795 : subroutine tdef_update(tdef,dtset,mpi_enreg,time,rprimd,gprimd,kg,mpsang,npwarr,ylm,ylmgr,current,update_vecpot_ind)
          -  +  -  +  -  
                      + ]
     173                 :             : 
     174                 :             :  !Arguments ------------------------------------
     175                 :             :  !scalars
     176                 :             :  class(tdef_type),   intent(inout) :: tdef
     177                 :             :  type(dataset_type), intent(inout) :: dtset
     178                 :             :  type(MPI_type),     intent(inout) :: mpi_enreg
     179                 :             :  real(dp),           intent(in)    :: time
     180                 :             :  real(dp),           intent(in)    :: rprimd(3,3)
     181                 :             :  real(dp),           intent(in)    :: gprimd(3,3)
     182                 :             :  integer,            intent(in)    :: kg(:,:)
     183                 :             :  integer,            intent(in)    :: mpsang
     184                 :             :  integer,            intent(in)    :: npwarr(:)
     185                 :             :  real(dp),           intent(in)    :: current(:,:)
     186                 :             :  real(dp),           intent(out)   :: ylm(:,:)
     187                 :             :  real(dp),           intent(out)   :: ylmgr(:,:,:)
     188                 :             :  logical, optional,  intent(in)    :: update_vecpot_ind
     189                 :             : 
     190                 :             :  !Local variables-------------------------------
     191                 :             :  character(len=500) :: msg
     192                 :             :  integer            :: i
     193                 :             :  logical            :: lvecpot_ind
     194                 :             :  real(dp)           :: tmp(3), expt
     195                 :             : 
     196                 :             : ! ***********************************************************************
     197                 :             : 
     198                 :             :  ! Update potential vector if time-dependent electric field perturbation is present
     199                 :        2916 :  select case (tdef%ef_type)
     200                 :             :    !No external field
     201                 :             :    case (0)
     202                 :             :    !Dirac pulse: vector potential is just an Heaviside function
     203                 :             :    case (1)
     204         [ +  + ]:        1121 :       if (abs(time-tdef%ef_tzero)<tol16) then
     205         [ +  + ]:          44 :          tdef%efield(:) = tdef%ef_ezero(:)
     206                 :             :       else
     207         [ +  + ]:        4440 :          tdef%efield(:) = zero
     208                 :             :       end if
     209         [ +  + ]:        1121 :       if (time >= tdef%ef_tzero) then
     210         [ +  + ]:        4324 :          tdef%vecpot_ext(:) = -tdef%ef_ezero(:)
     211                 :             :       end if
     212                 :             :    !"Finite" delta-kick pulse: Vector potential is a finite width sigmoid function
     213                 :             :    case (2)
     214                 :           0 :       expt = exp(-(time-tdef%ef_tzero)/tdef%ef_tau)
     215         [ #  # ]:           0 :       tdef%efield(:) = tdef%ef_ezero(:)/tdef%ef_tau * expt/(1+expt)**2
     216         [ #  # ]:           0 :       tdef%vecpot_ext(:) = -tdef%ef_ezero(:)/(1+expt)**2
     217                 :             :    !Pulse with sin^2 shape:
     218                 :             :    !E(t) = E0*cos(w*(t-t0))*sin^2(pi*(t-t0)/tau)
     219                 :             :    !A(t) = -(E0/2w)*sin(w*(t-t0))+E0/(4*(2pi/tau+w))*sin((2pi/tau+w)*(t-t0))+E0/(4(2pi/tau-w))*sin((2pi/tau-w)*(t-t0))
     220                 :             : !  case(2)
     221                 :             : !     if (time >= tdef%ef_tzero+tdef%ef_tau) then
     222                 :             : !        tdef%efield(:) = zero
     223                 :             : !     else if (time >= tdef%ef_tzero) then
     224                 :             : !        t = time-tdef%ef_tzero
     225                 :             : !        tdef%efield(:) = tdef%ef_ezero*cos(tdef%ef_omega*t)*sin(pi*t/tdef%ef_tau)**2
     226                 :             : !        tdef%vecpot_ext(:) = tdef%ef_ezero*(-sin(tdef%ef_omega*t)/(two*tdef%ef_omega) &
     227                 :             : !                                          & +sin(tdef%ef_sin_a*t)/(four*tdef%ef_sin_a) &
     228                 :             : !                                          & +sin(tdef%ef_sin_b*t)/(four*tdef%ef_sin_b))
     229                 :             : !     end if
     230                 :             :    case default
     231                 :           0 :       write(msg,"(a)") "Unknown electric field type - check the value of td_ef_type"
     232   [ +  -  -  + ]:        1795 :       ABI_ERROR(msg)
     233                 :             :  end select
     234                 :             : 
     235                 :        1795 :  lvecpot_ind = .true.
     236         [ +  + ]:        1795 :  if (present(update_vecpot_ind)) lvecpot_ind = update_vecpot_ind
     237                 :             : 
     238                 :             :  !Induced vector potential
     239                 :             :  !Should deal with sppol?! How?
     240                 :             :  !d^2A_ind/dt^2 = 4piJ(t)
     241                 :             :  !A_ind(t+dt) = 2*A_ind(t) - A_ind(t-dt) + 4*pi*dt**2*J(t)
     242         [ +  + ]:        1795 :  if (tdef%induced_vecpot) then
     243         [ +  + ]:         102 :     if (lvecpot_ind) then
     244         [ +  + ]:         404 :       tmp = tdef%vecpot_ind(:,2) ! t - 2dt
     245         [ +  + ]:         404 :       tdef%vecpot_ind(:,2) = tdef%vecpot_ind(:,1) ! t - dt
     246         [ +  + ]:         404 :       tdef%vecpot_ind(:,1) = 2*tdef%vecpot_ind(:,2) - tmp(:) + four*pi*(dtset%dtele**2)*current(:,1) ! t
     247                 :             :     end if
     248         [ +  + ]:         408 :     tdef%vecpot = tdef%vecpot_ext + tdef%vecpot_ind(:,1)
     249                 :             :  else
     250         [ +  + ]:        6772 :    tdef%vecpot = tdef%vecpot_ext
     251                 :             :  end if
     252                 :             : 
     253         [ +  + ]:        7180 :  tdef%vecpot_red = matmul(transpose(rprimd),tdef%vecpot)
     254                 :             : 
     255         [ +  + ]:        1795 :  if (tdef%ef_type /= 0) then
     256                 :             :    !Update the k+A grid used in cprojs
     257                 :             :    !Divide by 2pi here seems necessary
     258         [ +  + ]:        4484 :    do i = 1,3
     259         [ +  + ]:      112100 :       tdef%kpa(i,:) = dtset%kptns(i,:) + tdef%vecpot_red(i)/(two*pi)
     260                 :             :    end do
     261                 :             :    ! update the spherical harmonics (computed at k+G+A)
     262                 :             :    call initylmg(gprimd,kg,tdef%kpa,dtset%mkmem,mpi_enreg,mpsang,dtset%mpw,dtset%nband, &
     263   [ -  +  -  -  :        1121 :                & dtset%nkpt,npwarr,dtset%nsppol,0,rprimd,ylm,ylmgr)
          -  -  -  -  -  
          +  -  -  -  -  
          -  +  -  -  -  
          +  -  -  -  +  
          -  +  -  +  -  
          -  -  -  -  +  
          -  -  -  -  -  
                      - ]
     264                 :             :  end if
     265                 :             : 
     266                 :        1795 : end subroutine tdef_update
     267                 :             : !!***
     268                 :             : 
     269                 :             : !!****f* m_rttddft/tdef_restart
     270                 :             : !!
     271                 :             : !! NAME
     272                 :             : !!  tdef_restart
     273                 :             : !!
     274                 :             : !! FUNCTION
     275                 :             : !!  Update some values for restart of calculation with TD electric field
     276                 :             : !!  Essentially needed if we account for induced vector potential
     277                 :             : !!
     278                 :             : !! INPUTS
     279                 :             : !!  [tdef = tdef structure to update]
     280                 :             : !!  mpi_enreg = MPI communicators structure
     281                 :             : !!  restart_unit = unit of restart file to read
     282                 :             : !!
     283                 :             : !! OUTPUT
     284                 :             : !!  [tdef = updated tdef structure]
     285                 :             : !!
     286                 :             : !! SOURCE
     287                 :          20 : subroutine tdef_restart(tdef,mpi_enreg,restart_unit)
     288                 :             : 
     289                 :             :  !Arguments ------------------------------------
     290                 :             :  !scalars
     291                 :             :  class(tdef_type),   intent(inout) :: tdef
     292                 :             :  type(MPI_type),     intent(inout) :: mpi_enreg
     293                 :             :  integer,            intent(in)    :: restart_unit
     294                 :             : 
     295                 :             :  !Local variables-------------------------------
     296                 :             :  integer :: ierr
     297                 :             : 
     298                 :             : ! ***********************************************************************
     299                 :             : 
     300         [ +  + ]:          20 :  if (tdef%induced_vecpot) then
     301         [ +  - ]:           1 :       if (mpi_enreg%me == 0) then
     302                 :           1 :          read(restart_unit,*) tdef%vecpot_ind(:,2)
     303                 :           1 :          read(restart_unit,*) tdef%vecpot_ind(:,1)
     304                 :             :       end if
     305                 :             :  end if
     306                 :             :  !Send to all procs
     307                 :          20 :  call xmpi_bcast(tdef%vecpot_ind,0,mpi_enreg%comm_world,ierr)
     308                 :             : 
     309                 :          20 : end subroutine tdef_restart
     310                 :             : !!***
     311                 :             : 
     312   [ #  #  #  #  :           0 : end module m_rttddft_tdef
          #  #  #  #  #  
                #  #  # ]
     313                 :             : !!***
        

Generated by: LCOV version 2.3-1