LCOV - code coverage report
Current view: top level - src/67_common - m_eprenorms.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 80.8 % 78 63
Test Date: 2026-09-19 15:24:51 Functions: 71.4 % 7 5

            Line data    Source code
       1              : !!****m* ABINIT/m_eprenorms
       2              : !! NAME
       3              : !! m_eprenorms
       4              : !!
       5              : !! FUNCTION
       6              : !! This module contains datatypes to compute the renormalization of electronic states due to
       7              : !! eph coupling and temperature effects
       8              : !!
       9              : !! NOTES
      10              : !! This code is still under development and the API will change in the next versions.
      11              : !! Contact gmatteo
      12              : !!
      13              : !! COPYRIGHT
      14              : !! Copyright (C) 2001-2026 ABINIT group (YG)
      15              : !! This file is distributed under the terms of the
      16              : !! GNU General Public License, see ~abinit/COPYING
      17              : !! or http://www.gnu.org/copyleft/gpl.txt .
      18              : !!
      19              : !! SOURCE
      20              : 
      21              : #if defined HAVE_CONFIG_H
      22              : #include "config.h"
      23              : #endif
      24              : 
      25              : #include "abi_common.h"
      26              : 
      27              : module m_eprenorms
      28              : 
      29              :  use defs_basis
      30              :  use m_abicore
      31              :  use m_errors
      32              :  use m_xmpi
      33              :  use netcdf
      34              :  use m_nctk
      35              :  use m_ebands
      36              : 
      37              :  use m_crystal,      only : crystal_t
      38              :  use m_kpts,         only : listkk
      39              : 
      40              :  implicit none
      41              : 
      42              :  private
      43              : !!***
      44              : 
      45              : !!****t* m_eprenorms/eprenorms_t
      46              : !! NAME
      47              : !! eprenorms_t
      48              : !!
      49              : !! FUNCTION
      50              : !! Datatype gathering data for electron-phonon renormalization of the band structure
      51              : !!
      52              : !! SOURCE
      53              : 
      54              :  type,public :: eprenorms_t
      55              : 
      56              :   !scalars
      57              :   integer :: nkpt
      58              :   ! Number of kpoints
      59              : 
      60              :   integer :: nsppol
      61              :   ! Number of spin channels
      62              : 
      63              :   integer :: mband
      64              :   ! Maximum number of bands
      65              : 
      66              :   integer :: ntemp
      67              :   ! Number of temperatures
      68              : 
      69              :   !arrays
      70              :   real(dp), allocatable :: kpts(:,:)
      71              :   ! kpt(3,nkpt)
      72              :   ! Kpoints
      73              : 
      74              :   real(dp), allocatable :: temps(:)
      75              :   ! temps(ntemp)
      76              :   ! Temperatures
      77              : 
      78              :   real(dp), allocatable :: eigens(:,:,:)
      79              :   ! eigens(mband,nkpt,nsppol)
      80              :   ! Kohn-Sham eigenvalues
      81              : 
      82              :   real(dp), allocatable :: occs(:,:,:)
      83              :   ! occ(mband,nkpt,nsppol)
      84              :   ! Occupation numbers
      85              : 
      86              :   real(dp), allocatable :: renorms(:,:,:,:,:)
      87              :   ! renorms(2,mband,nkpt,nsppol,ntemp)
      88              :   ! Renormalization of the eigenvalues for each temperature
      89              : 
      90              :   real(dp), allocatable :: linewidth(:,:,:,:,:)
      91              :   ! linewidth(2,mband,nkpt,nsppol,ntemp)
      92              :   ! Electron-phonon induced linewidth of the eigens
      93              : 
      94              :  end type eprenorms_t
      95              : 
      96              :  public :: eprenorms_init
      97              :  public :: eprenorms_free
      98              :  public :: eprenorms_from_epnc
      99              :  public :: eprenorms_bcast
     100              : 
     101              :  public :: renorm_bst
     102              : !!***
     103              : 
     104              : CONTAINS  !============================================================================
     105              : !!***
     106              : 
     107              : !!****f* m_eprenorms/eprenorms_init
     108              : !! NAME
     109              : !! eprenorms_init
     110              : !!
     111              : !! FUNCTION
     112              : !!  Initializes an eprenorms_t datatype
     113              : !!
     114              : !! INPUTS
     115              : !!
     116              : !! OUTPUT
     117              : !!  Epren<eprenorms_t>=Datatype gathering electron-phonon renormalizations
     118              : !!
     119              : !! SOURCE
     120              : 
     121            3 : subroutine eprenorms_init(Epren,nkpt,nsppol,mband,ntemp)
     122              : 
     123              : !Arugments -----------------------------------
     124              : !scalars
     125              :  integer,intent(in) :: nkpt, nsppol, mband, ntemp
     126              :  type(eprenorms_t) :: Epren
     127              : !arrays
     128              : 
     129              : !*************************************************************************
     130              : 
     131              :  DBG_ENTER("COLL")
     132              : 
     133            3 :  Epren%nkpt = nkpt
     134            3 :  Epren%nsppol = nsppol
     135            3 :  Epren%mband = mband
     136            3 :  Epren%ntemp = ntemp
     137              : 
     138            9 :  ABI_MALLOC(Epren%temps,(Epren%ntemp))
     139            9 :  ABI_MALLOC(Epren%kpts,(3,Epren%nkpt))
     140           15 :  ABI_MALLOC(Epren%eigens,(Epren%mband,Epren%nkpt,Epren%nsppol))
     141           12 :  ABI_MALLOC(Epren%occs,(Epren%mband,Epren%nkpt,Epren%nsppol))
     142           18 :  ABI_MALLOC(Epren%renorms,(2,Epren%mband,Epren%nkpt,Epren%nsppol,Epren%ntemp))
     143           15 :  ABI_MALLOC(Epren%linewidth,(2,Epren%mband,Epren%nkpt,Epren%nsppol,Epren%ntemp))
     144              : 
     145              :  DBG_EXIT("COLL")
     146              : 
     147            3 : end subroutine eprenorms_init
     148              : !!***
     149              : 
     150              : !---------------------------------------------------------------------
     151              : 
     152              : !!****f* m_eprenorms/eprenorms_free
     153              : !! NAME
     154              : !! eprenorms_free
     155              : !!
     156              : !! FUNCTION
     157              : !! Deallocate all memory associated with eprenorms
     158              : !!
     159              : !! INPUTS
     160              : !! Epren<eprenorms_t>=The datatype to be freed
     161              : !!
     162              : !! SOURCE
     163              : 
     164           30 : subroutine eprenorms_free(Epren)
     165              : 
     166              : !Arguments -----------------------------------
     167              : !scalars
     168              :  type(eprenorms_t),intent(inout) :: Epren
     169              : 
     170              : !*********************************************************************
     171              : 
     172           30 :  ABI_SFREE(Epren%temps)
     173           30 :  ABI_SFREE(Epren%kpts)
     174           30 :  ABI_SFREE(Epren%eigens)
     175           30 :  ABI_SFREE(Epren%occs)
     176           30 :  ABI_SFREE(Epren%renorms)
     177           30 :  ABI_SFREE(Epren%linewidth)
     178              : 
     179           30 : end subroutine eprenorms_free
     180              : !!***
     181              : 
     182              : !---------------------------------------------------------------------
     183              : 
     184              : !!****f* m_eprenorms/eprenorms_from_epnc
     185              : !! NAME
     186              : !! eprenorms_from_epnc
     187              : !!
     188              : !! FUNCTION
     189              : !! Allocates and initializes the datatype from a _EP.nc file
     190              : !!
     191              : !! INPUTS
     192              : !! filename = name of the file to be read
     193              : !!
     194              : !! SIDE EFFECTS
     195              : !! Epren<eprenorms_t> = fields are initialized and filled with data from filename
     196              : !!
     197              : !! SOURCE
     198              : 
     199            3 : subroutine eprenorms_from_epnc(Epren,filename)
     200              : 
     201              : !Arguments -----------------------------------
     202              : !scalars
     203              :  character(len=fnlen),intent(in) :: filename
     204              :  type(eprenorms_t),intent(inout) :: Epren
     205              : 
     206              : !Local variables------------------------------
     207              :  integer :: nkpt, mband, nsppol, ntemp
     208              :  integer :: ncid
     209              : ! ************************************************************************
     210              : 
     211            3 :  NCF_CHECK(nctk_open_read(ncid, filename, xmpi_comm_self))
     212            3 :  NCF_CHECK(nctk_set_datamode(ncid))
     213              : 
     214            3 :  NCF_CHECK(nctk_get_dim(ncid, "number_of_kpoints", nkpt))
     215            3 :  NCF_CHECK(nctk_get_dim(ncid, "number_of_spins",nsppol))
     216            3 :  NCF_CHECK(nctk_get_dim(ncid, "max_number_of_states",mband))
     217            3 :  NCF_CHECK(nctk_get_dim(ncid, "number_of_temperature",ntemp))
     218              : 
     219            3 :  call eprenorms_init(Epren, nkpt, nsppol, mband, ntemp)
     220              : 
     221            3 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid,"reduced_coordinates_of_kpoints"), Epren%kpts))
     222            3 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid,"temperature"), Epren%temps))
     223            3 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid,"eigenvalues"), Epren%eigens))
     224            3 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid,"occupations"), Epren%occs))
     225            3 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid,"zero_point_motion"), Epren%renorms))
     226              :  ! TODO: This should be changed. What is stored is a linewidth, not a lifetime,
     227              :  ! we postone the change so as to not break compatibility
     228            3 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid,"lifetime"), Epren%linewidth))
     229              : 
     230            3 : end subroutine eprenorms_from_epnc
     231              : !!***
     232              : 
     233              : !---------------------------------------------------------------------
     234              : 
     235              : !!****f* m_eprenorms/eprenorms_bcast
     236              : !! NAME
     237              : !! eprenorms_bcast
     238              : !!
     239              : !! FUNCTION
     240              : !!  MPI broadcast all the content of eprenorms_t
     241              : !!
     242              : !! INPUTS
     243              : !!  master = Rank of master
     244              : !!  comm = MPI communicator
     245              : !!
     246              : !! SIDE EFFECTS
     247              : !!  Epren<eprenorms_t> = Data broadcasted on every node from master
     248              : !!
     249              : !! SOURCE
     250              : 
     251            3 : subroutine eprenorms_bcast(Epren,master,comm)
     252              : 
     253              : !Arguments -----------------------------------
     254              : !scalars
     255              :  integer,intent(in) :: master, comm
     256              :  type(eprenorms_t),intent(inout) :: Epren
     257              : 
     258              : !Local variables------------------------------
     259              : !scalars
     260              :  integer :: ierr
     261              : 
     262              : ! ************************************************************************
     263              : 
     264            3 :  if (xmpi_comm_size(comm) == 1) return
     265              : 
     266            0 :  call xmpi_bcast(Epren%nkpt, master, comm, ierr)
     267            0 :  call xmpi_bcast(Epren%nsppol, master, comm, ierr)
     268            0 :  call xmpi_bcast(Epren%mband, master, comm, ierr)
     269            0 :  call xmpi_bcast(Epren%ntemp, master, comm, ierr)
     270              : 
     271            0 :  if (xmpi_comm_rank(comm) /= master) then
     272            0 :   call eprenorms_init(Epren, Epren%nkpt, Epren%nsppol, Epren%mband, Epren%ntemp)
     273              :  end if
     274              : 
     275            0 :  call xmpi_bcast(Epren%kpts, master, comm, ierr)
     276            0 :  call xmpi_bcast(Epren%temps, master, comm, ierr)
     277            0 :  call xmpi_bcast(Epren%eigens, master, comm, ierr)
     278            0 :  call xmpi_bcast(Epren%occs, master, comm, ierr)
     279            0 :  call xmpi_bcast(Epren%renorms, master, comm, ierr)
     280            0 :  call xmpi_bcast(Epren%linewidth, master, comm, ierr)
     281              : 
     282              : end subroutine eprenorms_bcast
     283              : !!***
     284              : 
     285              : !---------------------------------------------------------------------
     286              : 
     287              : !!****f* m_eprenorms/renorm_bst
     288              : !! NAME
     289              : !! renorm_bst
     290              : !!
     291              : !! FUNCTION
     292              : !!  Renormalize the band structure Bst from data contained Epren
     293              : !!
     294              : !! INPUTS
     295              : !!  Epren<eprenorms_t> = datatype containing the elphon renormalization
     296              : !!  itemp = index of the temperature you want to use
     297              : !!  do_lifetime = .true. if we want to use imaginary eigenvalues (lifetime field)
     298              : !!
     299              : !! SIDE EFFECTS
     300              : !!  Bst<bands_t> : eigens are changed according to epren
     301              : !!                 linewidth is allocated and filled with data if do_linewidth
     302              : !!
     303              : !! SOURCE
     304              : 
     305           50 : subroutine renorm_bst(Epren,Bst,Cryst,itemp,do_lifetime,do_check)
     306              : 
     307              : !Arguments -----------------------------------
     308              : !scalars
     309              :  integer :: itemp
     310              :  logical,intent(in) :: do_lifetime
     311              :  logical,optional,intent(in) :: do_check
     312              :  type(eprenorms_t),intent(in) :: Epren
     313              :  type(ebands_t),intent(inout) :: Bst
     314              :  type(crystal_t),intent(in) :: Cryst
     315              : 
     316              : !Local variables------------------------------
     317              : !scalars
     318              :  integer :: isppol,ikpt,comm
     319              :  integer :: nband1, nband_tmp
     320              :  integer :: timrev, sppoldbl
     321              :  integer :: ik_eph
     322              :  real(dp) :: dksqmax
     323              :  logical :: check
     324              : !arrays
     325           50 :  integer,allocatable :: bs2eph(:,:)
     326              : 
     327              : ! ************************************************************************
     328              : 
     329           50 :  ABI_CHECK(Bst%nsppol == Epren%nsppol, "Nsppol should be the same")
     330              : 
     331           50 :  comm = xmpi_comm_self
     332              : 
     333           50 :  if(do_lifetime) then
     334          250 :    ABI_MALLOC(Bst%linewidth,(1,Bst%mband,Bst%nkpt,Bst%nsppol))
     335              :  end if
     336              : 
     337           50 :  check = .TRUE.
     338           50 :  if(present(do_check)) then
     339           50 :    check = do_check
     340              :  end if
     341              : 
     342           50 :  sppoldbl = 1 !; if (any(Cryst%symafm == -1) .and. Epren%nsppol == 1) nsppoldbl=2
     343          150 :  ABI_MALLOC(bs2eph, (BSt%nkpt*sppoldbl, 6))
     344           50 :  timrev = 1
     345              :  call listkk(dksqmax, Cryst%gmet, bs2eph, Epren%kpts, BSt%kptns, Epren%nkpt, Bst%nkpt, Cryst%nsym, &
     346           50 : &   sppoldbl, Cryst%symafm, Cryst%symrel, timrev, comm, use_symrec=.False.)
     347              : 
     348          100 :  do isppol=1,Bst%nsppol
     349          300 :    do ikpt=1,Bst%nkpt
     350          200 :      nband1 = Bst%nband(ikpt+(isppol-1)*Bst%nkpt)
     351          200 :      nband_tmp=MIN(nband1,Epren%mband)
     352              : 
     353          200 :      ik_eph = bs2eph(ikpt,1)
     354              : 
     355              :      !FIXME change check
     356          200 :      if (check) then
     357         1420 :        if (ANY(ABS(Bst%eig(1:MIN(10,nband_tmp),ikpt,isppol) - Epren%eigens(1:MIN(10,nband_tmp),ik_eph,isppol)) > tol3)) then
     358              :          !write(stdout,*) "eig : ",BSt%eig(1:MIN(10,nband_tmp),ikpt,isppol)
     359              :          !write(stdout,*) "eigens : ",Epren%eigens(1:MIN(10,nband_tmp),ikpt,isppol)
     360            0 :          ABI_ERROR("Error in eigenvalues, check the _EP.nc file with respect to your input file !")
     361              :        end if
     362         1420 :        if (ANY(ABS(Bst%occ(1:MIN(10,nband_tmp),ikpt,isppol) - Epren%occs(1:MIN(10,nband_tmp),ik_eph,isppol)) > tol3)) then
     363            0 :          ABI_ERROR("Error in occupations, check the _EP.nc file with respect to your input file !")
     364              :        end if
     365              :      end if
     366              : 
     367              :      ! Upgrade energies
     368         2280 :      Bst%eig(1:nband_tmp,ikpt,isppol) = BSt%eig(1:nband_tmp,ikpt,isppol) + Epren%renorms(1,1:nband_tmp,ik_eph,isppol,itemp)
     369              : 
     370          250 :      if (do_lifetime) then
     371         2280 :        Bst%linewidth(1,1:nband_tmp,ikpt,isppol) = Epren%linewidth(1,1:nband_tmp,ik_eph,isppol,itemp)
     372              :      end if
     373              :    end do
     374              :  end do
     375              : 
     376           50 :  ABI_FREE(bs2eph)
     377              : 
     378           50 : end subroutine renorm_bst
     379              : !!***
     380              : 
     381              : !---------------------------------------------------------------------
     382              : 
     383            0 : end module m_eprenorms
     384              : !!***
        

Generated by: LCOV version 2.3-1