LCOV - code coverage report
Current view: top level - src/78_eph - m_frohlich.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 94.3 % 492 464
Test Date: 2026-11-08 08:00:28 Functions: 100.0 % 12 12
Branches: 63.4 % 1226 777

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_frohlich
       2                 :             : !! NAME
       3                 :             : !!  m_frohlich
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!  Description
       7                 :             : !!
       8                 :             : !! COPYRIGHT
       9                 :             : !!  Copyright (C) 2018-2026 ABINIT group (VV, XG)
      10                 :             : !!  This file is distributed under the terms of the
      11                 :             : !!  GNU General Public License, see ~abinit/COPYING
      12                 :             : !!  or http://www.gnu.org/copyleft/gpl.txt .
      13                 :             : !!
      14                 :             : !! SOURCE
      15                 :             : 
      16                 :             : #if defined HAVE_CONFIG_H
      17                 :             : #include "config.h"
      18                 :             : #endif
      19                 :             : 
      20                 :             : #include "abi_common.h"
      21                 :             : 
      22                 :             : module m_frohlich
      23                 :             : 
      24                 :             :  use defs_basis
      25                 :             :  use m_abicore
      26                 :             :  use m_errors
      27                 :             :  use m_crystal
      28                 :             :  use m_ebands
      29                 :             :  use m_efmas_defs
      30                 :             :  use m_ifc
      31                 :             :  use m_dtset
      32                 :             : 
      33                 :             :  use m_fstrings,            only : sjoin, itoa
      34                 :             :  use m_gaussian_quadrature, only : cgqf
      35                 :             : 
      36                 :             :  implicit none
      37                 :             : 
      38                 :             :  private
      39                 :             : !!***
      40                 :             : 
      41                 :             : !----------------------------------------------------------------------
      42                 :             : 
      43                 :             : !!****t* m_frohlich/frohlich_t
      44                 :             : !! NAME
      45                 :             : !!  frohlich_t
      46                 :             : !!
      47                 :             : !! FUNCTION
      48                 :             : !!  Description
      49                 :             : !!
      50                 :             : !! SOURCE
      51                 :             : 
      52                 :             :  type,public :: frohlich_t
      53                 :             : 
      54                 :             :   integer :: kind = 0
      55                 :             :    ! Type of the Fr\"ohlich model
      56                 :             :    ! used to access the calculations of various properties
      57                 :             :    ! 0 -> ndeg != 1 && ndeg != 3, generalized Fr\"ohlich model
      58                 :             :    ! 1 -> ndeg = 1, standard (possibly anisotropic) Fr\"ohlich model
      59                 :             :    ! 2 -> ndeg = 3, cubic generalized Fr\"ohlich model with 3-fold degeneracy
      60                 :             : 
      61                 :             :  ! Geometry ------------------------------------
      62                 :             : 
      63                 :             :   real(dp) :: ucvol
      64                 :             :    ! Real space unit cell volume
      65                 :             : 
      66                 :             :   real(dp) :: gmet(3,3)
      67                 :             :     ! Reciprocal space metric
      68                 :             : 
      69                 :             : 
      70                 :             :  ! Electroncic subspace -----------------------
      71                 :             : 
      72                 :             :   logical :: isinitel = .false.
      73                 :             :    ! Flag indicating that the electronic subspace has been initialized
      74                 :             : 
      75                 :             :   real(dp) :: kpt(3)
      76                 :             :    ! k-point characterizing the electronic subspace, i.e. the k-point at which
      77                 :             :    ! the effective mass tensor is obtained (usually, CBM or VBM)
      78                 :             : 
      79                 :             :   integer :: ndeg
      80                 :             :    ! Number of degenerate bands taken into account
      81                 :             : 
      82                 :             :   complex(dp), allocatable :: eig2_diag_cart(:,:,:,:)
      83                 :             :    ! Band curvature double tensor in Cartesian coordinates
      84                 :             :    ! (3, 3, ndeg, ndeg)
      85                 :             : 
      86                 :             :   real(dp) :: band_params(3)
      87                 :             :    ! Parameters describing electronic bands
      88                 :             :    ! The meaning of this arrayd depends on the value of the kind variable
      89                 :             :    ! kind = 0 -> undefined
      90                 :             :    ! kind = 1 -> inverse effetive masses along the 100, 010 and 001 directions
      91                 :             :    ! kind = 2 -> Luttinger-Kohn parameters A, B, C
      92                 :             : 
      93                 :             :   logical :: lutt_warn(3) = .false.
      94                 :             : 
      95                 :             :   real(dp), allocatable :: sqrt_efmas_avg(:)
      96                 :             :    ! Square root of effective mass averaged over q-sphere for each band
      97                 :             :    ! (ndeg)
      98                 :             : 
      99                 :             :   logical, allocatable :: saddle_warn(:)
     100                 :             :    ! Signals if the k-point characterizing the electronic subspace is a
     101                 :             :    ! saddle-point for each of the degenerate bands
     102                 :             :    ! (ndeg)
     103                 :             : 
     104                 :             :   real(dp) :: sqrt_efmas_tot
     105                 :             :    ! Total square root of effective mass average
     106                 :             : 
     107                 :             :   real(dp), allocatable :: invefmas(:,:)
     108                 :             :    ! Inverse electronic effective masses along
     109                 :             :    ! kind = 1 -> 100, 010, 001 directions
     110                 :             :    ! kind = 2 -> 100, 110, 111 directions
     111                 :             :    ! (ndeg, 3)
     112                 :             : 
     113                 :             : 
     114                 :             :  ! Vibrational (phonon) subspace ---------------
     115                 :             : 
     116                 :             :   logical :: isinitph = .false.
     117                 :             :    ! Flag indicating that the phonon subspace has been initialized
     118                 :             : 
     119                 :             :   integer :: natom
     120                 :             :    ! Number of atoms in the cell
     121                 :             : 
     122                 :             :   integer :: nqdir
     123                 :             :    ! Number of points for spherical integration used to compute ZPR and other
     124                 :             :    ! quantities
     125                 :             : 
     126                 :             :   real(dp), allocatable :: unit_qdir(:,:)
     127                 :             :    ! Unit q-vectors representing reciprocal space directions used to compute
     128                 :             :    ! ZPR and other quantities
     129                 :             :    ! (3, nqdir)
     130                 :             : 
     131                 :             :   real(dp), allocatable :: weights_qdir(:)
     132                 :             :    ! Gaussian quadrature weights used for spherical intragraion over q-vectors
     133                 :             :    ! (nqdir)
     134                 :             : 
     135                 :             :   real(dp), allocatable :: dielt_qdir(:)
     136                 :             :    ! High-frequency dielectric constant for each q-vector direction
     137                 :             :    ! (nqdir)
     138                 :             : 
     139                 :             :   real(dp), allocatable :: phfreq_qdir(:,:)
     140                 :             :    ! Phonon frequencies for each mode and q-vector direction
     141                 :             :    ! (3*natom, nqdir)
     142                 :             : 
     143                 :             :   real(dp), allocatable :: polarity_qdir(:,:,:)
     144                 :             :    ! Mode polarity vectors for each mode and q-vector direction
     145                 :             :    ! (3, 3*natom, nqdir)
     146                 :             : 
     147                 :             :   real(dp), allocatable :: proj_polarity_qdir(:,:)
     148                 :             :    ! Projections of mode polarity vectors for each mode and q-vector direction
     149                 :             :    ! (3*natom, nqdir)
     150                 :             : 
     151                 :             :   real(dp), allocatable :: investar(:,:)
     152                 :             :    ! Inverse effective dielectric constant for each mode and q-vector
     153                 :             :    ! (3*natom, nqdir)
     154                 :             : 
     155                 :             :   real(dp), allocatable :: dielavg(:)
     156                 :             :    ! Dielectric average over q-vectors for each mode (Eq. (26) of [deMelo2023])
     157                 :             :    ! (3*natom)
     158                 :             : 
     159                 :             :   logical, allocatable :: isiractive(:)
     160                 :             :    ! Flags to detect the infrared-active phonon modes
     161                 :             :    ! (3*natom)
     162                 :             : 
     163                 :             :   real(dp) :: dielt_eff
     164                 :             :    ! Effective dielectric constant in the strong-coupling regime
     165                 :             : 
     166                 :             :   real(dp) :: phfreq_eff
     167                 :             :    ! Effective LO phonon frequency in the strong-coupling regime
     168                 :             : 
     169                 :             : 
     170                 :             :  ! Weak-coupling parameters --------------------
     171                 :             : 
     172                 :             :   real(dp), allocatable :: zpr_band(:)
     173                 :             :    ! Zero-point renormalization energy for each band (Eq. (17) of [deMelo2023])
     174                 :             :    ! (ndeg)
     175                 :             : 
     176                 :             :   logical :: sign_warn = .false.
     177                 :             :    ! Sginals an error if a saddle-point is encountered or bands contribute to
     178                 :             :    ! the ZPR with different signs
     179                 :             : 
     180                 :             :   real(dp) :: zpr_gamma
     181                 :             :    ! Correction to the ZPR taking into account the infrared divergence of the
     182                 :             :    ! electron-phonon coupling in the Fr\"ohlich model
     183                 :             : 
     184                 :             :   real(dp) :: zpr
     185                 :             :    ! Total ZPR for these bands and k-point
     186                 :             : 
     187                 :             :   real(dp) :: enpol_wc
     188                 :             :    ! Fr\"ohlich polaron formation energy in the weak-coupling regime
     189                 :             :    ! (Eq. (26) of [deMelo2023])
     190                 :             : 
     191                 :             :   real(dp), allocatable :: zpr_k(:,:,:)
     192                 :             :    ! Direction dependent ZPR (Eq. (86) of [Guster2021])
     193                 :             :    ! (3, ndeg, 3)
     194                 :             : 
     195                 :             :   real(dp), allocatable :: invpolmas(:,:)
     196                 :             :    ! Inverse Fr\"ohlich polaron effective masses in the weak-coupling regime
     197                 :             :    ! (Sec. III A, B of [Guster2021])
     198                 :             :    ! kind = 1 -> 100, 010, 001 directions
     199                 :             :    ! kind = 2 -> 100, 110, 111 directions
     200                 :             :    ! (ndeg, 3)
     201                 :             : 
     202                 :             : 
     203                 :             :   contains
     204                 :             : 
     205                 :             :     procedure :: init_ph => frohlich_init_ph
     206                 :             :      ! Initialization of a vibrational (phonon) subspace parameters
     207                 :             : 
     208                 :             :     procedure :: init_el => frohlich_init_el
     209                 :             :      ! Initialization of an electronic subspace parameters
     210                 :             : 
     211                 :             :     procedure :: free_ph => frohlich_free_ph
     212                 :             :      ! Free memory allocated to the vibrational subspace
     213                 :             : 
     214                 :             :     procedure :: free_el => frohlich_free_el
     215                 :             :      ! Free memory allocated to the electronic subspace
     216                 :             :      ! and other related quantities
     217                 :             : 
     218                 :             :     procedure :: calc_zpr => frohlich_calc_zpr
     219                 :             :      ! Calculate the zero-point renormalization energy corresponding to the
     220                 :             :      ! weak-coupling treatment of the Fr\"ohlich model
     221                 :             : 
     222                 :             :     procedure :: calc_polaronmass => frohlich_calc_polaronmass
     223                 :             :      ! Calculate the polaron effective mass corresponding to the weak-coupling
     224                 :             :      ! treatment of the Fr\"ohlich model; available for kind = 1 or 2
     225                 :             : 
     226                 :             :     ! procedure :: ncwrite => frohlich_ncwrite
     227                 :             :      ! Write main dimensions and header on a netcdf file
     228                 :             : 
     229                 :             : 
     230                 :             :  end type frohlich_t
     231                 :             : !!***
     232                 :             : 
     233                 :             : public :: frohlichmodel_zpr         ! Main routine to compute ZPR
     234                 :             : public :: frohlichmodel_polaronmass ! Main routine to compute polaron effective
     235                 :             :                                     ! masses
     236                 :             : 
     237                 :             : contains !=====================================================================
     238                 :             : !!***
     239                 :             : 
     240                 :             : !!****f* m_frohlich/frohlichmodel_polaronmass
     241                 :             : !! NAME
     242                 :             : !!  frohlichmodel_polaronmass
     243                 :             : !!
     244                 :             : !! FUNCTION
     245                 :             : !!  Main routine to compute the polaron effective masses of the generalized
     246                 :             : !! Fr\"ohlich model and other related quantities
     247                 :             : !!
     248                 :             : !! INPUTS
     249                 :             : !!  cryst<crystal_t>=Structure defining the unit cell
     250                 :             : !!  dtset<dataset_type>=All input variables for this dataset.
     251                 :             : !!  efmasdeg(nkpt_rbz) <type(efmasdeg_type)>= information about the band
     252                 :             : !! degeneracy at each k point
     253                 :             : !!  efmasval(mband,nkpt_rbz) <type(efmasdeg_type)>= double tensor datastructure
     254                 :             : !!   efmasval(:,:)%eig2_diag band curvature double tensor
     255                 :             : !!  ifc<ifc_type>=contains the dynamical matrix and the IFCs.
     256                 :             : !!
     257                 :             : !! NOTES
     258                 :             : !!  This routine has to be merged with the frohlichmodel_zpr routine, and their
     259                 :             : !!  text output needs to be refined. For now, they are being kept to be
     260                 :             : !!  compatible with the legacy unit tests.
     261                 :             : !!
     262                 :             : !! SOURCE
     263                 :             : 
     264   [ -  +  -  + ]:           1 : subroutine frohlichmodel_polaronmass(frohlich, cryst, dtset, efmasdeg, efmasval, ifc)
     265                 :             : 
     266                 :             : !Arguments ------------------------------------
     267                 :             : !scalars
     268                 :             :  class(frohlich_t),intent(inout) :: frohlich
     269                 :             :  type(crystal_t),intent(in) :: cryst
     270                 :             :  type(dataset_type),intent(in) :: dtset
     271                 :             :  type(ifc_type),intent(in) :: ifc
     272                 :             : !arrays
     273                 :             :  type(efmasdeg_type), intent(in) :: efmasdeg(:)
     274                 :             :  type(efmasval_type), intent(in) :: efmasval(:,:)
     275                 :             : 
     276                 :             : !Local variables-------------------------------
     277                 :             : !scalar
     278                 :             :  integer :: nu, ikpt, ideg, ndeg
     279                 :             :  integer :: iqdir
     280                 :             : !arrays
     281                 :             :  real(dp) :: kpt(3)
     282                 :             : 
     283                 :             : ! *************************************************************************
     284                 :             : 
     285                 :             :  ! Initalize phonon and dielectric subspace
     286                 :           1 :  call frohlich%init_ph(cryst, dtset%efmas_ntheta, ifc)
     287                 :             : 
     288                 :             :  ! For each k-point (with possible degeneracy), initialize an inistance of the
     289                 :             :  ! generalize Fr\"ohlich model and calculate related quantities
     290         [ +  + ]:           2 :  do ikpt=1,dtset%nkpt
     291         [ +  + ]:           4 :    kpt(:) = dtset%kptns(:, ikpt)
     292                 :             : 
     293         [ +  + ]:           4 :    do ideg=efmasdeg(ikpt)%deg_range(1),efmasdeg(ikpt)%deg_range(2)
     294                 :             :      ndeg = efmasdeg(ikpt)%degs_bounds(2, ideg) - &
     295                 :           2 :        efmasdeg(ikpt)%degs_bounds(1, ideg) + 1
     296                 :             : 
     297                 :           2 :      call frohlich%init_el(cryst, kpt, ndeg, efmasval(ideg, ikpt)%eig2_diag)
     298                 :           2 :      call frohlich%calc_zpr()
     299                 :           2 :      call frohlich%calc_polaronmass()
     300                 :             : 
     301                 :             :      ! Luttinger parameters if applicable
     302         [ +  + ]:           2 :      if (frohlich%ndeg == 3) then
     303                 :             : 
     304   [ +  +  +  -  :           4 :        if (.not. (any(frohlich%saddle_warn))) then
                   +  - ]
     305   [ +  +  +  -  :           4 :          if (any(frohlich%lutt_warn)) then
                   -  + ]
     306                 :             : 
     307                 :           0 :            write(ab_out, '(2a)') ch10, &
     308                 :           0 :              ' Luttinger parameters could not be determined:'
     309                 :             : 
     310         [ #  # ]:           0 :            if (frohlich%lutt_warn(1)) then
     311                 :             :              write(ab_out, '(a)')  '     Predicted degeneracies for &
     312                 :           0 :                &deg_dim = 3 are not met for (100) direction.'
     313                 :             :            endif
     314                 :             : 
     315         [ #  # ]:           0 :            if (frohlich%lutt_warn(2)) then
     316                 :             :              write(ab_out, '(a)')  '     Predicted degeneracies for &
     317                 :           0 :                &deg_dim = 3 are not met for (111) direction.'
     318                 :             :            endif
     319                 :             : 
     320         [ #  # ]:           0 :            if (frohlich%lutt_warn(3)) then
     321                 :             :              write(ab_out, '(a)')  '     Predicted degeneracies for &
     322                 :           0 :                &deg_dim = 3 are not met for (110) direction.'
     323                 :             :            endif
     324                 :             : 
     325                 :           0 :            write(ab_out, '(a)') ch10
     326                 :             :          else
     327                 :             :            write(ab_out, '(a,3f14.6)') &
     328                 :           1 :              '   Luttinger parameters (A, B, C) (a.u.): ', &
     329                 :           2 :              frohlich%band_params(:)
     330                 :             :          endif
     331                 :             :        endif
     332                 :             : 
     333                 :             :        ! Print inverse electronic effective masses in the output
     334                 :           1 :        write(ab_out, '(a)') repeat('-', 80)
     335                 :             :        write(ab_out, '(a)') '   Polaron properties from the generalized &
     336                 :           1 :          &Froehlich model'
     337                 :           1 :        write(ab_out, '(a)') repeat('-', 80)
     338                 :           1 :        write(ab_out, '(a)') '   Polar modes'
     339                 :           1 :        write(ab_out, '(a)') '   ##      Frequency(meV)            Epsilon*'
     340                 :             : 
     341                 :             :        ! For a cubic material, dielectric tensor and phonon frequencies at Gamma
     342                 :             :        ! do not depend on the q-vector direction
     343                 :           1 :        iqdir = 1
     344         [ +  + ]:           4 :        do nu = 4,3*cryst%natom
     345         [ +  + ]:           4 :          if (frohlich%isiractive(nu)) then
     346                 :           1 :           write(ab_out,'(2x,i3,5x,f15.6,5x,f15.6)') nu, &
     347                 :           1 :             frohlich%phfreq_qdir(nu, iqdir)*Ha_eV*1000.0_dp, &
     348                 :           2 :             one/frohlich%investar(nu, iqdir)
     349                 :             :          endif
     350                 :             :        enddo
     351                 :             : 
     352                 :           1 :        write(ab_out, '(a)') ' '
     353                 :           1 :        write(ab_out, '(a,f10.2)') '   ZPR (meV): ', &
     354                 :           2 :          frohlich%zpr_k(1, 1, 1)*Ha_eV*1000.0_dp
     355                 :           1 :        write(ab_out, '(a)') ' '
     356                 :             :        write(ab_out, '(a)') '   Electronic effective mass (a.u.) &
     357                 :           1 :          &along 3 directions'
     358                 :           1 :        write(ab_out, '(a, 3f15.6)')'    Direction 100:         ', &
     359         [ +  + ]:           5 :          one/frohlich%invefmas(:, 1)
     360                 :           1 :        write(ab_out, '(a, 3f15.6)')'    Direction 110:         ', &
     361         [ +  + ]:           5 :          one/frohlich%invefmas(:, 2)
     362                 :           1 :        write(ab_out, '(a, 3f15.6)')'    Direction 111:         ', &
     363         [ +  + ]:           5 :          one/frohlich%invefmas(:, 3)
     364                 :             : 
     365                 :             :      ! Print inverse polaron effective masses in the output
     366                 :           1 :        write(ab_out, '(a)') ' '
     367                 :           1 :        write(ab_out, '(a)') '   Polaron effective mass (a.u.) along 3 directions'
     368                 :           1 :        write(ab_out, '(a, 3f15.6)') '    Direction 100:         ', &
     369         [ +  + ]:           5 :          one/frohlich%invpolmas(:, 1)
     370                 :           1 :        write(ab_out, '(a, 3f15.6)') '    Direction 110:         ', &
     371         [ +  + ]:           5 :          one/frohlich%invpolmas(:, 2)
     372                 :           1 :        write(ab_out, '(a, 3f15.6)') '    Direction 111:         ', &
     373         [ +  + ]:           5 :          one/frohlich%invpolmas(:, 3)
     374                 :           1 :        write(ab_out, '(a)')' '
     375                 :             :        write(ab_out, '(a)')'   Sum rule of inverse polaron masses check-up &
     376                 :           1 :          &(for convergence purposes):'
     377                 :           1 :        write(ab_out,'(a, 3f15.6)')'    Direction 100:         ', &
     378         [ +  + ]:           5 :          sum(frohlich%invpolmas(:, 1))
     379                 :           1 :        write(ab_out,'(a, 3f15.6)')'    Direction 110:         ', &
     380         [ +  + ]:           5 :          sum(frohlich%invpolmas(:, 2))
     381                 :           1 :        write(ab_out,'(a, 3f15.6)')'    Direction 111:         ', &
     382         [ +  + ]:           5 :          sum(frohlich%invpolmas(:, 3))
     383                 :             :      endif
     384                 :             : 
     385                 :           3 :      call frohlich%free_el()
     386                 :             :    enddo
     387                 :             :  enddo
     388                 :             : 
     389                 :           1 :  call frohlich%free_ph()
     390                 :             : 
     391                 :           1 : end subroutine frohlichmodel_polaronmass
     392                 :             : !!***
     393                 :             : 
     394                 :             : 
     395                 :             : !!****f* m_frohlich/frohlichmodel_zpr
     396                 :             : !! NAME
     397                 :             : !!  frohlichmodel_zpr
     398                 :             : !!
     399                 :             : !! FUNCTION
     400                 :             : !!  Main routine to compute the ZPR of the generalized Fr\"ohlich model and
     401                 :             : !! other related quantities
     402                 :             : !!
     403                 :             : !! INPUTS
     404                 :             : !!  cryst<crystal_t>=Structure defining the unit cell
     405                 :             : !!  dtset<dataset_type>=All input variables for this dataset.
     406                 :             : !!  efmasdeg(nkpt_rbz) <type(efmasdeg_type)>= information about the band
     407                 :             : !! degeneracy at each k point
     408                 :             : !!  efmasval(mband,nkpt_rbz) <type(efmasdeg_type)>= double tensor datastructure
     409                 :             : !!   efmasval(:,:)%eig2_diag band curvature double tensor
     410                 :             : !!  ifc<ifc_type>=contains the dynamical matrix and the IFCs.
     411                 :             : !!
     412                 :             : !! SOURCE
     413                 :             : 
     414   [ -  +  -  + ]:           2 : subroutine frohlichmodel_zpr(frohlich, cryst, dtset, efmasdeg, efmasval, ifc)
     415                 :             : 
     416                 :             : !Arguments ------------------------------------
     417                 :             : !scalars
     418                 :             :  class(frohlich_t),intent(inout) :: frohlich
     419                 :             :  type(crystal_t),intent(in) :: cryst
     420                 :             :  type(dataset_type),intent(in) :: dtset
     421                 :             :  type(ifc_type),intent(in) :: ifc
     422                 :             : !arrays
     423                 :             :  type(efmasdeg_type), intent(in) :: efmasdeg(:)
     424                 :             :  type(efmasval_type), intent(in) :: efmasval(:,:)
     425                 :             : 
     426                 :             : !Local variables-------------------------------
     427                 :             : !scalar
     428                 :             :  integer :: nu, ikpt, ideg, ndeg, iband
     429                 :             : !arrays
     430                 :             :  real(dp) :: kpt(3)
     431                 :             : 
     432                 :             : ! *************************************************************************
     433                 :             : 
     434                 :             :  ! Initalize phonon and dielectric subspace
     435                 :           2 :  call frohlich%init_ph(cryst, dtset%efmas_ntheta, ifc)
     436                 :             : 
     437                 :             :  ! Dielectric average
     438                 :           2 :  write(ab_out, '(a)') repeat('-', 80)
     439                 :           2 :  write(ab_out, '(a)') ' Dielectric average (EQ. 25 Melo2022)'
     440                 :           2 :  write(ab_out, '(a)') repeat('-', 80)
     441                 :             :  write(ab_out, '(a)') &
     442                 :           2 :    ' Mode    <1/epsilon*SQRT(w_LO/2)>              Cumulative sum'
     443                 :             : 
     444         [ +  + ]:          11 :  do nu=4,3*cryst%natom
     445                 :           9 :    write(ab_out, '(i5,f28.12,f28.12)') nu, &
     446         [ +  + ]:          74 :      frohlich%dielavg(nu), sum(frohlich%dielavg(1:nu))
     447                 :             :  enddo
     448                 :           2 :  write(ab_out, '(a)') repeat('-', 80)
     449                 :             : 
     450                 :             :  ! Infrared ZPR correction (does not depend on the electronic subspace)
     451                 :           2 :  write(ab_out, '(6a,f14.6,a,f14.6,a)') ch10, &
     452                 :             :    ' Rough correction to the ZPR, to take into account the missing q=0 piece &
     453                 :           2 :    &using Frohlich model:', ch10, &
     454                 :             :    ' (+ for occupied states, - for unoccupied states) * zpr_q0_fact / &
     455                 :           2 :    &(Nqpt_full_bz)**(1/3) ', ch10, &
     456                 :           2 :    ' where Nqpt_full_bz=number of q wavevectors in full BZ, and zpr_q0_fact=',&
     457                 :           4 :    frohlich%zpr_gamma, ' Ha=', frohlich%zpr_gamma*Ha_eV, ' eV'
     458                 :             : 
     459                 :             :  ! For each k-point (with possible degeneracy), initialize an inistance of the
     460                 :             :  ! generalize Fr\"ohlich model and calculate ZPR and other related quantities
     461         [ +  + ]:           6 :  do ikpt=1,dtset%nkpt
     462         [ +  + ]:          16 :    kpt(:) = dtset%kptns(:, ikpt)
     463                 :             : 
     464         [ +  + ]:          17 :    do ideg=efmasdeg(ikpt)%deg_range(1),efmasdeg(ikpt)%deg_range(2)
     465                 :             :      ndeg = efmasdeg(ikpt)%degs_bounds(2, ideg) - &
     466                 :          11 :        efmasdeg(ikpt)%degs_bounds(1, ideg) + 1
     467                 :             : 
     468                 :          11 :      call frohlich%init_el(cryst, kpt, ndeg, efmasval(ideg, ikpt)%eig2_diag)
     469                 :          11 :      call frohlich%calc_zpr()
     470                 :             : 
     471                 :             :      ! Print ZPR results for each k-point
     472         [ +  + ]:          11 :      if (ndeg == 1) then
     473                 :           9 :        write(ab_out, '(2a,3(f6.3,a),i5)') ch10, &
     474                 :           9 :          ' - At k-point (', kpt(1), ',', kpt(2), ',', kpt(3), '), band ', &
     475                 :          18 :          efmasdeg(ikpt)%degs_bounds(1,ideg)
     476                 :             :      else
     477                 :           2 :        write(ab_out, '(2a,3(f6.3,a),i5,a,i5)') ch10, &
     478                 :           2 :          ' - At k-point (', kpt(1), ',', kpt(2), ',', kpt(3), '), bands ', &
     479                 :           2 :          efmasdeg(ikpt)%degs_bounds(1,ideg), ' through ', &
     480                 :           4 :          efmasdeg(ikpt)%degs_bounds(2,ideg)
     481                 :             :      endif
     482                 :             : 
     483                 :             :      ! Luttinger parameters if applicable
     484         [ +  + ]:          11 :      if (frohlich%kind == 2) then
     485                 :             : 
     486   [ +  +  +  -  :           4 :        if (.not. (any(frohlich%saddle_warn))) then
                   +  - ]
     487   [ +  +  +  -  :           4 :          if (any(frohlich%lutt_warn)) then
                   -  + ]
     488                 :             : 
     489                 :           0 :            write(ab_out, '(2a)') ch10, &
     490                 :           0 :              ' Luttinger parameters could not be determined:'
     491                 :             : 
     492         [ #  # ]:           0 :            if (frohlich%lutt_warn(1)) then
     493                 :             :              write(ab_out, '(a)')  '     Predicted degeneracies for &
     494                 :           0 :                &deg_dim = 3 are not met for (100) direction.'
     495                 :             :            endif
     496                 :             : 
     497         [ #  # ]:           0 :            if (frohlich%lutt_warn(2)) then
     498                 :             :              write(ab_out, '(a)')  '     Predicted degeneracies for &
     499                 :           0 :                &deg_dim = 3 are not met for (111) direction.'
     500                 :             :            endif
     501                 :             : 
     502         [ #  # ]:           0 :            if (frohlich%lutt_warn(3)) then
     503                 :             :              write(ab_out, '(a)')  '     Predicted degeneracies for &
     504                 :           0 :                &deg_dim = 3 are not met for (110) direction.'
     505                 :             :            endif
     506                 :             : 
     507                 :           0 :            write(ab_out, '(a)') ch10
     508                 :             :          else
     509                 :             :            write(ab_out, '(a,3f14.6)') &
     510                 :           1 :              ' Luttinger parameters (A, B, C) [at. units]: ', &
     511                 :           2 :              frohlich%band_params(:)
     512                 :             :          endif
     513                 :             :        endif
     514                 :             :      endif
     515                 :             : 
     516                 :             :      ! Effective mass average and ZPR
     517         [ +  + ]:          25 :      do iband=1,ndeg
     518         [ +  + ]:          25 :        if (frohlich%saddle_warn(iband)) then
     519                 :           5 :          write(ab_out, '(a,i5,a)') ' Band ', &
     520                 :           5 :            efmasdeg(ikpt)%degs_bounds(1, ideg) + iband - 1, ' SADDLE POINT - &
     521                 :          10 :            &Frohlich effective mass and ZPR cannot be defined. '
     522                 :             :        else
     523                 :           9 :          write(ab_out, '(a,i5,a,f14.10)') ' Band ', &
     524                 :           9 :            efmasdeg(ikpt)%degs_bounds(1, ideg) + iband - 1, ' Angular average &
     525                 :           9 :            &effective mass for Frohlich model (<m**0.5>)**2= ', &
     526                 :             :            sign(frohlich%sqrt_efmas_avg(iband)**2, &
     527                 :          18 :            frohlich%sqrt_efmas_avg(iband))
     528                 :             :        endif
     529                 :             :      enddo
     530                 :             : 
     531         [ +  + ]:          11 :      if (.not. frohlich%sign_warn) then
     532                 :             :        write(ab_out, '(2a)') &
     533                 :           7 :          ' Angular and band average effective mass and ZPR for Frohlich model.'
     534                 :             : 
     535                 :           7 :        write(ab_out, '(a,es16.6)') ' Value of     (<<m**0.5>>)**2 = ', &
     536         [ +  + ]:          23 :          (sum(abs(frohlich%sqrt_efmas_avg(:))) / ndeg)**2
     537                 :             : 
     538                 :           7 :        write(ab_out, '(a,es16.6)') ' Absolute Value of <<m**0.5>> = ', &
     539         [ +  + ]:          23 :          (sum(abs(frohlich%sqrt_efmas_avg(:))) / ndeg)
     540                 :             : 
     541                 :             :        write(ab_out, '(a,es16.6,a,es16.6,a)') &
     542                 :           7 :          ' ZPR from Frohlich model      = ', frohlich%zpr, ' Ha=', &
     543                 :          14 :          frohlich%zpr*Ha_eV,' eV'
     544                 :             :      else
     545                 :             :        write(ab_out, '(a)') ' Angular and band average effective mass for &
     546                 :           4 :          &Frohlich model cannot be defined because of a sign problem.'
     547                 :             :      endif
     548                 :             : 
     549                 :          15 :      call frohlich%free_el()
     550                 :             :    enddo
     551                 :             :  enddo
     552                 :             : 
     553                 :           2 :  call frohlich%free_ph()
     554                 :             : 
     555                 :           2 : end subroutine frohlichmodel_zpr
     556                 :             : !!***
     557                 :             : 
     558                 :             : 
     559                 :             : !!****f* m_frohlich/frohlich_free_el
     560                 :             : !! NAME
     561                 :             : !!  frohlich_free_el
     562                 :             : !!
     563                 :             : !! FUNCTION
     564                 :             : !!  Deallocate dynamic memory related to the electronic subspace and other
     565                 :             : !! related quantities
     566                 :             : !!
     567                 :             : !! INPUTS
     568                 :             : !!
     569                 :             : !! SOURCE
     570                 :             : 
     571                 :          13 : subroutine frohlich_free_el(self)
     572                 :             : 
     573                 :             : !Arguments ------------------------------------
     574                 :             :  class(frohlich_t),intent(inout) :: self
     575                 :             : ! *************************************************************************
     576                 :             : 
     577                 :          13 :  self%isinitel = .false.
     578                 :             : 
     579                 :             :  ! real
     580         [ +  - ]:          13 :  ABI_SFREE(self%sqrt_efmas_avg)
     581         [ +  - ]:          13 :  ABI_SFREE(self%zpr_band)
     582         [ +  + ]:          13 :  ABI_SFREE(self%invpolmas)
     583         [ +  + ]:          13 :  ABI_SFREE(self%zpr_k)
     584         [ +  + ]:          13 :  ABI_SFREE(self%invefmas)
     585                 :             : 
     586                 :             :  ! complex
     587         [ +  - ]:          13 :  ABI_SFREE(self%eig2_diag_cart)
     588                 :             : 
     589                 :             :  ! logical
     590         [ +  - ]:          13 :  ABI_SFREE(self%saddle_warn)
     591                 :             : 
     592                 :          13 : end subroutine frohlich_free_el
     593                 :             : !!***
     594                 :             : 
     595                 :             : 
     596                 :             : !!****f* m_frohlich/frohlich_free_ph
     597                 :             : !! NAME
     598                 :             : !!  frohlich_free_ph
     599                 :             : !!
     600                 :             : !! FUNCTION
     601                 :             : !!  Deallocate dynamic memory related to the vibrational subspace
     602                 :             : !!
     603                 :             : !! INPUTS
     604                 :             : !!
     605                 :             : !! SOURCE
     606                 :             : 
     607                 :           3 : subroutine frohlich_free_ph(self)
     608                 :             : 
     609                 :             : !Arguments ------------------------------------
     610                 :             :  class(frohlich_t),intent(inout) :: self
     611                 :             : ! *************************************************************************
     612                 :             : 
     613                 :           3 :  self%isinitph = .false.
     614                 :             : 
     615                 :             :  ! real
     616         [ +  - ]:           3 :  ABI_SFREE(self%unit_qdir)
     617         [ +  - ]:           3 :  ABI_SFREE(self%weights_qdir)
     618         [ +  - ]:           3 :  ABI_SFREE(self%dielt_qdir)
     619         [ +  - ]:           3 :  ABI_SFREE(self%phfreq_qdir)
     620         [ +  - ]:           3 :  ABI_SFREE(self%polarity_qdir)
     621         [ +  - ]:           3 :  ABI_SFREE(self%proj_polarity_qdir)
     622         [ +  - ]:           3 :  ABI_SFREE(self%investar)
     623         [ +  - ]:           3 :  ABI_SFREE(self%dielavg)
     624                 :             : 
     625                 :             :  ! logical
     626         [ +  - ]:           3 :  ABI_SFREE(self%isiractive)
     627                 :             : 
     628                 :           3 : end subroutine frohlich_free_ph
     629                 :             : !!***
     630                 :             : 
     631                 :             : 
     632                 :             : !!****f* m_frohlich/frohlich_calc_polaronmass
     633                 :             : !! NAME
     634                 :             : !!  frohlich_calc_polaronmass
     635                 :             : !!
     636                 :             : !! FUNCTION
     637                 :             : !!  Description
     638                 :             : !!
     639                 :             : !! INPUTS
     640                 :             : !!  self<frohlich_t> = Datatype gathering information on the Fr\"ohlich model
     641                 :             : !!
     642                 :             : !! OUTPUT
     643                 :             : !!  self<frohlich_t> = Datatype gathering information on the Fr\"ohlich model
     644                 :             : !!
     645                 :             : !! SOURCE
     646                 :             : 
     647                 :           2 : subroutine frohlich_calc_polaronmass(self)
     648                 :             : 
     649                 :             : !Arguments ------------------------------------
     650                 :             : !scalars
     651                 :             :  class(frohlich_t), intent(inout) :: self
     652                 :             : 
     653                 :             : !Local variables-------------------------------
     654                 :             : !scalars
     655                 :             :  integer :: ii
     656                 :             :  integer :: ikdir, nkdir
     657                 :             :  integer :: ik, nkgrid
     658                 :             :  integer :: lwork, info
     659                 :             :  integer :: nu, iband
     660                 :             :  integer :: ixi, nxi
     661                 :             :  integer :: iqdir
     662                 :             :  integer :: sigma
     663                 :             :  real(dp) :: deltak, minefmas
     664                 :             :  real(dp) :: xi, qlen
     665                 :             :  real(dp) :: tmp
     666                 :             : !arrays
     667                 :             :  real(dp) :: id33(3, 3)
     668                 :             :  real(dp) :: kpt(3), unit_kdir(3, 3)
     669                 :             :  real(dp) :: k_plus_q(3)
     670                 :           2 :  real(dp), allocatable :: eigenvec(:,:), eigenval(:)
     671                 :           2 :  real(dp), allocatable :: invefmas(:,:)
     672                 :           2 :  real(dp), allocatable :: lutt_eigenvec(:,:,:,:), lutt_eigenval(:,:,:)
     673                 :           2 :  real(dp), allocatable :: lk_h(:,:)
     674                 :           2 :  real(dp), allocatable :: phfreq(:), investar(:)
     675                 :           2 :  real(dp), allocatable :: intsum(:,:,:,:)
     676                 :           2 :  real(dp), allocatable :: zpr(:,:,:), zpr_ddk(:,:)
     677                 :           2 :  real(dp), allocatable :: intsuminv(:,:)
     678                 :           2 :  complex(dp), allocatable :: work(:)
     679                 :             : ! *************************************************************************
     680                 :             : 
     681                 :             :  ! TODO: check if the electronic and phonon parts are initialized
     682   [ -  +  +  -  :           6 :  ABI_MALLOC(self%invpolmas, (self%ndeg, 3))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     683                 :             : 
     684         [ +  + ]:           2 :  if (self%kind == 2) then
     685                 :             :    ! Polaron effective masses in the triply-degenerate case
     686                 :             :    ! (Eq. (86) of [Guster2021])
     687                 :             : 
     688                 :             :    ! Initialization of the diagonalization routine
     689                 :             :    ! TODO: this part is common for many routines -> initialize once and store
     690                 :             :    ! necessary variables as local state constants in the datatype
     691   [ -  +  +  -  :           4 :    ABI_MALLOC(eigenvec, (self%ndeg, self%ndeg))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     692   [ -  +  +  -  :           3 :    ABI_MALLOC(eigenval, (self%ndeg))
          +  -  +  -  -  
                +  -  + ]
     693   [ +  -  -  +  :           3 :    ABI_MALLOC(work, (3*self%ndeg - 2))
          +  -  +  -  +  
             -  -  +  -  
                      + ]
     694                 :           1 :    lwork = -1
     695                 :             :    call dsyev('V', 'U', self%ndeg, eigenvec(:,:), self%ndeg, eigenval(:), &
     696                 :           1 :      work, lwork, info)
     697                 :           1 :    lwork = int(work(1))
     698                 :           1 :    ABI_FREE(work)
     699   [ -  +  +  -  :           3 :    ABI_MALLOC(work, (lwork))
          +  -  +  -  -  
                +  -  + ]
     700                 :             : 
     701                 :             :    ! Inverse effectiv mass tensor for 100, 110 and 111 directions
     702                 :             :    ! used to obtain the material-dependent characteristic wavevector length
     703                 :             :    nkdir = 3
     704         [ +  + ]:           4 :    unit_kdir(:, 1) = (/1, 0, 0/)
     705         [ +  + ]:           4 :    unit_kdir(:, 2) = (/1, 1, 0/)/sqrt(2.0)
     706         [ +  + ]:           4 :    unit_kdir(:, 3) = (/1, 1, 1/)/sqrt(3.0)
     707   [ -  +  +  -  :           3 :    ABI_MALLOC(invefmas, (self%ndeg, nkdir))
          +  -  +  -  -  
                +  -  + ]
     708   [ -  +  +  -  :           2 :    ABI_MALLOC(self%invefmas, (self%ndeg, nkdir))
          -  +  -  +  -  
                      + ]
     709                 :             : 
     710                 :             :    ! 100: 2A, 2B (two-fold)
     711                 :           1 :    invefmas(1, 1) = two*self%band_params(1)
     712                 :           1 :    invefmas(2, 1) = two*self%band_params(2)
     713                 :           1 :    invefmas(3, 1) = two*self%band_params(2)
     714                 :             :    ! 110: A + B + C, 2B, A + B - C
     715                 :             :    invefmas(1, 2) = self%band_params(1) + self%band_params(2) + &
     716                 :           1 :      self%band_params(3)
     717                 :             :    invefmas(2, 2) = min(two*self%band_params(2), self%band_params(1) + &
     718                 :           1 :      self%band_params(2) - self%band_params(3))
     719                 :             :    invefmas(3, 2) = max(two*self%band_params(2), self%band_params(1) + &
     720                 :           1 :      self%band_params(2) - self%band_params(3))
     721                 :             :    ! 111: 2/3*(A + 2B + 2C), 2/3*(A + 2B - C) (two-fold)
     722                 :             :    invefmas(1, 3) = two*(self%band_params(1) + two*self%band_params(2) + &
     723                 :           1 :      two*self%band_params(3)) / three
     724                 :             :    invefmas(2, 3) = two*(self%band_params(1) + two*self%band_params(2) - &
     725                 :           1 :      self%band_params(3)) / three
     726                 :           1 :    invefmas(3, 3) = invefmas(2, 3)
     727                 :             : 
     728   [ +  +  +  + ]:          13 :    self%invefmas(:,:) = invefmas(:,:)
     729                 :             : 
     730                 :             :    ! Setting up the parameter to obtain the second derivative of the ZPR with
     731                 :             :    ! the finite differences (FD) method (Eqs. (80), (86) of [Guster2021])
     732                 :             :    ! FD: number of points
     733                 :             :    nkgrid = 3
     734                 :             :    ! FD: material-dependent length scale <--> lowest optical frequency
     735                 :           4 :    iqdir = 1
     736   [ +  +  +  +  :          13 :    minefmas = one / maxval(abs(invefmas(:,:)))
          +  +  +  -  -  
                +  -  - ]
     737                 :           1 :    deltak = sqrt(two*minefmas*self%phfreq_qdir(4, iqdir) / 1000.0)
     738                 :             : 
     739                 :             :    ! FD: Luttinger eigenvalues and eigenvectors in the symmetry inequivalent
     740                 :             :    ! cubic directions to be used in the ZPR calculations
     741   [ -  +  +  -  :           6 :    ABI_MALLOC(lutt_eigenvec, (self%ndeg, self%ndeg, nkgrid, nkdir))
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  -  +  -  
                      + ]
     742   [ -  +  +  -  :           4 :    ABI_MALLOC(lutt_eigenval, (self%ndeg, nkgrid, nkdir))
          +  -  +  -  +  
             -  -  +  -  
                      + ]
     743                 :             : 
     744   [ +  +  +  +  :          40 :    lutt_eigenval(:,:,:) = zero
                   +  + ]
     745         [ +  + ]:           4 :    do ikdir=1,nkdir
     746         [ +  + ]:          13 :      do ik=1,nkgrid
     747         [ +  + ]:          36 :        kpt(:) = (ik - one)*deltak*unit_kdir(:, ikdir)
     748                 :             :        call lk_hamiltonian(self%band_params(:), kpt(:), &
     749                 :           9 :          lutt_eigenvec(:,:, ik, ikdir))
     750                 :             :        call dsyev('V', 'U', self%ndeg, lutt_eigenvec(:,:, ik, ikdir), &
     751                 :          12 :          self%ndeg, lutt_eigenval(:, ik, ikdir), work(:), lwork, info)
     752                 :             :      enddo
     753                 :             :    enddo
     754                 :             : 
     755                 :             :    ! Cubic system is assumed: phonon frequencies and permitivity at Gamma
     756                 :             :    ! do not depend on the q-vector direction
     757                 :           1 :    iqdir = 1
     758   [ +  -  -  +  :           3 :    ABI_MALLOC(phfreq, (3*self%natom))
          +  -  +  -  +  
             -  -  +  -  
                      + ]
     759   [ -  +  +  -  :           2 :    ABI_MALLOC(investar, (3*self%natom))
             -  +  -  + ]
     760         [ +  + ]:           7 :    phfreq(:) = self%phfreq_qdir(:, iqdir)
     761         [ +  + ]:           7 :    investar(:) = self%investar(:, iqdir)
     762                 :             : 
     763                 :             :    ! Effective mass sign
     764                 :           1 :    sigma = 1
     765         [ +  - ]:           1 :    if (self%band_params(1) < 0) sigma = -1
     766                 :             : 
     767                 :             :    ! 3x3 Identity matrix
     768                 :           1 :    id33(:,:) = zero
     769         [ +  + ]:           4 :    do ii=1,3
     770                 :           4 :      id33(ii, ii) = one
     771                 :             :    enddo
     772                 :             : 
     773                 :             :    ! FD: main loop
     774                 :             :    ! nqidr = 2*ntheta**2 (ntheta = nxi)
     775                 :           1 :    nxi = sqrt(one*self%nqdir/2)
     776   [ -  +  +  -  :           6 :    ABI_MALLOC(intsum, (self%ndeg, self%ndeg, nkgrid, nkdir))
          -  +  +  -  +  
          -  +  -  +  -  
          +  -  -  +  -  
                      + ]
     777   [ -  +  +  -  :           4 :    ABI_MALLOC(zpr, (nkgrid, self%ndeg, nkdir))
          +  -  +  -  +  
             -  -  +  -  
                      + ]
     778   [ -  +  +  -  :           2 :    ABI_MALLOC(self%zpr_k, (nkgrid, self%ndeg, nkdir))
          -  +  -  +  -  
                      + ]
     779   [ -  +  +  -  :           4 :    ABI_MALLOC(lk_h, (self%ndeg, self%ndeg))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     780   [ -  +  +  -  :           3 :    ABI_MALLOC(intsuminv, (self%ndeg, self%ndeg))
          -  +  +  -  -  
                +  -  + ]
     781                 :             : 
     782                 :             :    ! Values of ZPR (Eq. (86) of [Guster2021]) to be used in FD
     783   [ +  +  +  +  :          40 :    zpr(:,:,:) = zero
                   +  + ]
     784         [ +  + ]:           4 :    do nu=4,3*self%natom
     785                 :             : 
     786                 :             :      ! Summation over the infrared-active phonon modes
     787         [ +  + ]:           4 :      if (self%isiractive(nu)) then
     788                 :             : 
     789         [ +  + ]:           4 :        do ikdir=1,nkdir
     790         [ +  + ]:          13 :          do iband=1,self%ndeg
     791         [ +  + ]:          39 :            do ik=1,nkgrid
     792         [ +  + ]:         108 :              kpt(:)  = (ik - one)*deltak*unit_kdir(:, ikdir)
     793                 :             : 
     794         [ +  + ]:        2763 :              do ixi=0,nxi
     795                 :        2727 :                xi = ixi*pi / (two*nxi)
     796         [ +  + ]:        2727 :                if (ixi == nxi) xi = xi - tol8
     797                 :             : 
     798                 :             :                ! q-vector length = (omega/A)^{1/2}*tan(xi)
     799                 :        2727 :                qlen = sqrt(phfreq(nu) / abs(self%band_params(1)))*tan(xi)
     800         [ +  + ]:    54542754 :                do iqdir=1,self%nqdir
     801         [ +  + ]:   218160000 :                  k_plus_q(:) = kpt(:) + qlen*self%unit_qdir(:, iqdir)
     802                 :             :                  call lk_hamiltonian(self%band_params(:), k_plus_q(:), &
     803                 :    54540000 :                    lk_h(:,:))
     804                 :             : 
     805                 :             :                  intsum(:,:, ik, ikdir) = &
     806                 :             :                    abs(lutt_eigenval(iband, ik, ikdir)*id33(:,:)) - (sigma * &
     807   [ +  +  +  + ]:   709020000 :                    lk_h(:,:) + phfreq(nu)*id33(:,:))
     808                 :             : 
     809                 :    54540000 :                  call mat3inv(intsum(:,:, ik, ikdir), intsuminv(:,:))
     810                 :             : 
     811                 :             :                  tmp = dot_product(lutt_eigenvec(:, iband, 2, ikdir), &
     812   [ +  -  +  -  :  1145340000 :                    matmul(intsuminv(:,:), lutt_eigenvec(:, iband, 2, ikdir)))
          +  -  -  +  -  
          +  +  +  +  +  
          +  +  +  +  +  
                      - ]
     813                 :             : 
     814                 :             :                  zpr(ik, iband, ikdir) = zpr(ik, iband, ikdir) + &
     815                 :             :                    investar(nu)*phfreq(nu)*tmp*sqrt(phfreq(nu) / &
     816                 :             :                    abs(self%band_params(1))) / cos(xi)**2 * &
     817                 :    54542727 :                    self%weights_qdir(iqdir)
     818                 :             :                enddo
     819                 :             :              enddo
     820                 :             :            enddo
     821                 :             :          enddo
     822                 :             :        enddo
     823                 :             : 
     824                 :             :      endif
     825                 :             :    enddo
     826   [ +  +  +  +  :          40 :    zpr(:,:,:) = half*quarter*piinv*sigma/nxi * zpr(:,:,:)
                   +  + ]
     827   [ +  +  +  +  :          40 :    self%zpr_k(:,:,:) = zpr(:,:,:)
                   +  + ]
     828                 :             : 
     829                 :             :    ! FD: actual finite differences to obtain the second derivative of ZPR
     830                 :             :    ! (Eq. (80) of [Guster2021])
     831   [ -  +  +  -  :           3 :    ABI_MALLOC(zpr_ddk, (self%ndeg, nkdir))
          +  -  +  -  -  
                +  -  + ]
     832                 :             : 
     833   [ +  +  +  + ]:          13 :    zpr_ddk(:,:) = zero
     834         [ +  + ]:           4 :    do ikdir=1,nkdir
     835         [ +  + ]:          13 :      do iband=1,self%ndeg
     836                 :             :        ! Copied from the previous implementation
     837                 :             :        ! Does not look like a usual FD expression...
     838                 :             :        zpr_ddk(iband, ikdir) = four/three *(zpr(2, iband, ikdir) - &
     839                 :             :          zpr(1, iband, ikdir) - (zpr(3, iband, ikdir) - &
     840                 :          12 :          zpr(1, iband, ikdir)) / 16.0_dp) * two/deltak**2
     841                 :             :      enddo
     842                 :             :    enddo
     843                 :             : 
     844         [ +  + ]:           4 :    do ikdir=1,nkdir
     845         [ +  + ]:          13 :      do iband=1,self%ndeg
     846                 :             :        self%invpolmas(iband, ikdir) = &
     847                 :          12 :          two/deltak**2 * lutt_eigenval(iband, 2, ikdir) + zpr_ddk(iband, ikdir)
     848                 :             :      enddo
     849                 :             :    enddo
     850                 :             : 
     851         [ -  + ]:           1 :    ABI_FREE(eigenvec)
     852         [ -  + ]:           1 :    ABI_FREE(eigenval)
     853         [ -  + ]:           1 :    ABI_FREE(work)
     854                 :           1 :    ABI_FREE(invefmas)
     855         [ -  + ]:           1 :    ABI_FREE(lutt_eigenvec)
     856         [ -  + ]:           1 :    ABI_FREE(lutt_eigenval)
     857         [ -  + ]:           1 :    ABI_FREE(phfreq)
     858         [ -  + ]:           1 :    ABI_FREE(investar)
     859         [ -  + ]:           1 :    ABI_FREE(intsum)
     860         [ -  + ]:           1 :    ABI_FREE(zpr)
     861         [ -  + ]:           1 :    ABI_FREE(lk_h)
     862         [ -  + ]:           1 :    ABI_FREE(zpr_ddk)
     863         [ -  + ]:           1 :    ABI_FREE(intsuminv)
     864                 :             :  endif
     865                 :             : 
     866                 :           2 : end subroutine frohlich_calc_polaronmass
     867                 :             : !!***
     868                 :             : 
     869                 :             : 
     870                 :             : !!****f* m_frohlich/frohlich_calc_zpr
     871                 :             : !! NAME
     872                 :             : !!  frohlich_calc_zpr
     873                 :             : !!
     874                 :             : !! FUNCTION
     875                 :             : !!  Description
     876                 :             : !!
     877                 :             : !! INPUTS
     878                 :             : !!  self<frohlich_t> = Datatype gathering information on the Fr\"ohlich model
     879                 :             : !!
     880                 :             : !! OUTPUT
     881                 :             : !!  self<frohlich_t> = Datatype gathering information on the Fr\"ohlich model
     882                 :             : !!
     883                 :             : !! SOURCE
     884                 :             : 
     885                 :          13 : subroutine frohlich_calc_zpr(self)
     886                 :             : 
     887                 :             : !Arguments ------------------------------------
     888                 :             : !scalars
     889                 :             :  class(frohlich_t), intent(inout) :: self
     890                 :             : 
     891                 :             : !Local variables-------------------------------
     892                 :             : !scalars
     893                 :             :  integer :: iqdir, nu
     894                 :             :  integer :: iband, jband
     895                 :             :  integer :: lwork, info
     896                 :             : !arrays
     897                 :          13 :  real(dp), allocatable :: efmas_qdir(:,:)
     898                 :          13 :  real(dp), allocatable :: invefmas_avg(:)
     899                 :          13 :  real(dp), allocatable :: eigenval(:), rwork(:)
     900                 :          13 :  complex(dp), allocatable :: eigenvec(:,:), work(:)
     901                 :          13 :  complex(dp), allocatable :: f3d(:,:)
     902                 :          13 :  logical, allocatable :: efmas_pos(:)
     903                 :             : ! *************************************************************************
     904                 :             : 
     905                 :             :  ! TODO: check if the electronic and phonon parts are initialized
     906                 :             : 
     907                 :             :  ! Initialization of the diagonalization routine for degenerate case
     908   [ -  +  +  -  :          39 :  ABI_MALLOC(eigenval, (self%ndeg))
          +  -  +  -  -  
                +  -  + ]
     909         [ +  + ]:          13 :  if (self%ndeg > 1) then
     910   [ -  +  +  -  :          12 :    ABI_MALLOC(eigenvec, (self%ndeg, self%ndeg))
          -  +  +  -  +  
             -  -  +  -  
                      + ]
     911                 :           3 :    lwork = -1
     912   [ -  +  +  -  :           9 :    ABI_MALLOC(rwork, (3*self%ndeg - 2))
          +  -  -  +  -  
                      + ]
     913         [ -  + ]:           3 :    ABI_MALLOC(work, (1))
     914                 :             :    call zheev('V', 'U', self%ndeg, eigenvec(:,:), self%ndeg, eigenval(:), &
     915                 :           3 :      work(:), lwork, rwork(:), info)
     916                 :           3 :    lwork = int(work(1))
     917                 :           3 :    ABI_FREE(work)
     918   [ -  +  +  -  :           9 :    ABI_MALLOC(work, (lwork))
          +  -  +  -  -  
                +  -  + ]
     919                 :             :  endif
     920                 :             : 
     921   [ -  +  +  -  :          52 :  ABI_MALLOC(f3d, (self%ndeg, self%ndeg))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     922   [ -  +  +  -  :          39 :  ABI_MALLOC(invefmas_avg, (self%ndeg))
          +  -  +  -  -  
                +  -  + ]
     923   [ -  +  +  -  :          39 :  ABI_MALLOC(efmas_pos, (self%ndeg))
          +  -  +  -  -  
                +  -  + ]
     924   [ -  +  +  -  :          52 :  ABI_MALLOC(efmas_qdir, (self%ndeg, self%nqdir))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     925   [ -  +  +  -  :          26 :  ABI_MALLOC(self%sqrt_efmas_avg, (self%ndeg))
          -  +  -  +  -  
                      + ]
     926   [ -  +  +  -  :          26 :  ABI_MALLOC(self%saddle_warn, (self%ndeg))
          -  +  -  +  -  
                      + ]
     927   [ -  +  +  -  :          26 :  ABI_MALLOC(self%zpr_band, (self%ndeg))
          -  +  -  +  -  
                      + ]
     928                 :             : 
     929                 :             :  ! Effective mass tensor in q-vector directions
     930         [ +  + ]:      260013 :  do iqdir=1,self%nqdir
     931                 :             : 
     932                 :             :    ! Band curvature tensor (inverse effective mass)
     933         [ +  + ]:      620000 :    do iband=1,self%ndeg
     934         [ +  + ]:     1260000 :      do jband=1,self%ndeg
     935   [ -  +  +  -  :     1920000 :        f3d(iband, jband) = dot_product(self%unit_qdir(:, iqdir), matmul( &
          +  -  +  -  -  
                +  -  + ]
     936   [ +  +  +  +  :    20840000 :          self%eig2_diag_cart(:,:, iband, jband), self%unit_qdir(:, iqdir)))
          +  +  +  +  +  
          -  +  -  +  -  
             +  +  +  - ]
     937                 :             :      enddo
     938                 :             :    enddo
     939                 :             : 
     940                 :             :    ! Band curvature tensor diagonalization
     941         [ +  + ]:      260000 :    if (self%ndeg == 1) then
     942                 :      200000 :      eigenval(1) = f3d(1, 1)
     943                 :             :    else
     944   [ +  +  +  + ]:      660000 :      eigenvec(:,:) = f3d(:,:)
     945         [ +  + ]:      220000 :      eigenval(:) = zero
     946         [ +  + ]:      320000 :      work(:) = zero
     947         [ +  + ]:      420000 :      rwork(:) = zero
     948                 :             :      call zheev('V', 'U', self%ndeg, eigenvec(:,:), self%ndeg, eigenval(:), &
     949                 :       60000 :        work(:), lwork, rwork(:), info)
     950         [ -  + ]:       60000 :      ABI_CHECK(info == 0, sjoin("zheev returned info: ", itoa(info)))
     951                 :             :    endif
     952                 :             : 
     953         [ +  + ]:      620013 :    efmas_qdir(:, iqdir) = one/eigenval(:)
     954                 :             :  enddo
     955                 :             : 
     956                 :             :  ! Integration over the q-sphere: square root of the effective mass average and
     957                 :             :  ! ZPR for each band (Eq. (17) of [deMelo2023])
     958         [ +  + ]:          31 :  self%saddle_warn(:) = .false.
     959         [ +  + ]:          31 :  self%sqrt_efmas_avg(:) = zero
     960         [ +  + ]:          31 :  self%zpr_band(:) = zero
     961         [ +  + ]:          31 :  invefmas_avg(:) = zero
     962         [ +  + ]:      260013 :  do iqdir=1,self%nqdir
     963                 :             :    ! square root of the effective mass average
     964                 :             :    self%sqrt_efmas_avg(:) = self%sqrt_efmas_avg(:) + &
     965         [ +  + ]:      620000 :      self%weights_qdir(iqdir)*sqrt(abs(efmas_qdir(:, iqdir)))
     966                 :             : 
     967                 :             :    ! ZPR
     968         [ +  + ]:     1460000 :    do nu=4,3*self%natom
     969                 :             :      self%zpr_band(:) = self%zpr_band(:) + (self%weights_qdir(iqdir) * &
     970                 :             :        self%investar(nu, iqdir)*sqrt(self%phfreq_qdir(nu, iqdir) * &
     971         [ +  + ]:     2960000 :        abs(efmas_qdir(:, iqdir))))
     972                 :             :    enddo
     973                 :             : 
     974                 :             :    ! Inverse effective mass average: used to obtain the sign of the ZPR
     975                 :             :    invefmas_avg(:) = invefmas_avg(:) + &
     976         [ +  + ]:      620000 :      self%weights_qdir(iqdir)/efmas_qdir(:, iqdir)
     977                 :             : 
     978                 :             :    ! Check for saddle-points
     979   [ +  +  +  + ]:      260018 :    if (iqdir == 1) efmas_pos(:) = (efmas_qdir(:, iqdir) > 0)
     980         [ +  + ]:      620013 :    do iband=1,self%ndeg
     981         [ +  + ]:      620000 :      if (efmas_pos(iband) .neqv. (efmas_qdir(iband, iqdir) > 0)) then
     982                 :       26700 :        self%saddle_warn(iband) = .true.
     983                 :             :      endif
     984                 :             :    enddo
     985                 :             :  enddo
     986         [ +  + ]:          31 :  self%sqrt_efmas_avg(:) = quarter*piinv*self%sqrt_efmas_avg(:)
     987         [ +  + ]:          31 :  self%zpr_band(:) = sqrthalf*quarter*piinv*self%zpr_band(:)
     988         [ +  + ]:          31 :  invefmas_avg(:) = quarter*piinv*invefmas_avg(:)
     989                 :             : 
     990                 :             :  ! Check for the sign problem and caclulate total ZPR and polaron formation
     991                 :             :  ! energy in the weak-coupling regime
     992                 :          13 :  self%sign_warn = .false.
     993         [ +  + ]:          31 :  do iband=1,self%ndeg
     994   [ +  +  -  + ]:          18 :    if (self%saddle_warn(iband) .or. &
     995                 :          13 :      (efmas_pos(iband) .neqv. efmas_pos(1))) then
     996                 :           5 :      self%sign_warn = .true.
     997                 :             :    else
     998                 :             :      self%sqrt_efmas_avg(iband) = &
     999                 :          13 :        sign(self%sqrt_efmas_avg(iband), invefmas_avg(iband))
    1000                 :             : 
    1001                 :          13 :      self%zpr_band(iband) = sign(self%zpr_band(iband), invefmas_avg(iband))
    1002                 :             :    endif
    1003                 :             :  enddo
    1004                 :             : 
    1005         [ +  + ]:          13 :  if (.not. self%sign_warn) then
    1006         [ +  + ]:          22 :    self%zpr = -sum(self%zpr_band(:)) / self%ndeg
    1007         [ +  + ]:          22 :    self%sqrt_efmas_tot = sum(self%sqrt_efmas_avg(:)) / self%ndeg
    1008         [ +  + ]:          75 :    self%enpol_wc = -self%sqrt_efmas_tot*sum(self%dielavg(:))
    1009                 :             :  endif
    1010                 :             : 
    1011         [ -  + ]:          13 :  ABI_FREE(eigenval)
    1012         [ -  + ]:          13 :  ABI_FREE(f3d)
    1013         [ -  + ]:          13 :  ABI_FREE(invefmas_avg)
    1014         [ -  + ]:          13 :  ABI_FREE(efmas_pos)
    1015         [ -  + ]:          13 :  ABI_FREE(efmas_qdir)
    1016         [ +  + ]:          13 :  if (self%ndeg > 1) then
    1017         [ -  + ]:           3 :    ABI_FREE(eigenvec)
    1018         [ -  + ]:           3 :    ABI_FREE(rwork)
    1019         [ -  + ]:           3 :    ABI_FREE(work)
    1020                 :             :  endif
    1021                 :             : 
    1022   [ -  +  -  +  :          13 : end subroutine frohlich_calc_zpr
                   -  + ]
    1023                 :             : !!***
    1024                 :             : 
    1025                 :             : 
    1026                 :             : !!****f* m_frohlich/frohlich_init_el
    1027                 :             : !! NAME
    1028                 :             : !!  frohlich_init_el
    1029                 :             : !!
    1030                 :             : !! FUNCTION
    1031                 :             : !!  Description
    1032                 :             : !!
    1033                 :             : !! INPUTS
    1034                 :             : !!  self<frohlich_t> = Datatype gathering information on the Fr\"ohlich model
    1035                 :             : !!  cryst<crystal_t> = Structure defining the unit cell
    1036                 :             : !!    %rprimd(3, 3) = real space primitvie vectors
    1037                 :             : !!  kpt(3) = k-point characterizing the electronic subspace
    1038                 :             : !!  ndeg = Number of degenerate bands
    1039                 :             : !!  eig2_diag(3, 3, ndeg, ndeg) = Band curvature double tensor
    1040                 :             : !!
    1041                 :             : !! OUTPUT
    1042                 :             : !!  self<frohlich_t> = Datatype gathering information on the Fr\"ohlich model
    1043                 :             : !!
    1044                 :             : !! SOURCE
    1045                 :             : 
    1046                 :          13 : subroutine frohlich_init_el(self, cryst, kpt, ndeg, eig2_diag)
    1047                 :             : 
    1048                 :             : !Arguments ------------------------------------
    1049                 :             : !scalars
    1050                 :             :  class(frohlich_t), intent(inout) :: self
    1051                 :             :  type(crystal_t), intent(in) :: cryst
    1052                 :             :  integer,intent(in) :: ndeg
    1053                 :             : !arrays
    1054                 :             :  real(dp), intent(in) :: kpt(3)
    1055                 :             :  complex(dp), intent(in) :: eig2_diag(3, 3, ndeg, ndeg)
    1056                 :             : 
    1057                 :             : !Local variables-------------------------------
    1058                 :             : !scalars
    1059                 :             :  integer :: lwork, info
    1060                 :             :  integer :: iband, jband
    1061                 :             :  integer :: idir, ipar
    1062                 :             : !arrays
    1063                 :             :  real(dp) :: unit_kdir(3, 3)
    1064                 :          26 :  real(dp) :: eigenval(ndeg), lutt_eigenval(ndeg, ndeg)
    1065                 :          13 :  real(dp), allocatable :: rwork(:)
    1066                 :          26 :  complex(dp) :: eigenvec(ndeg, ndeg), lutt_eigenvec(ndeg, ndeg)
    1067                 :          13 :  complex(dp), allocatable :: work(:)
    1068                 :             :  logical :: lutt_found(3)
    1069                 :             : ! *************************************************************************
    1070                 :             : 
    1071         [ +  + ]:          52 :  self%kpt(:) = kpt(:)
    1072                 :          13 :  self%ndeg = ndeg
    1073                 :             : 
    1074                 :             :  ! Initialize the band curvatutre double tensor in Cartesian coordiantes
    1075   [ -  +  +  -  :          52 :  ABI_MALLOC(self%eig2_diag_cart, (3, 3, ndeg, ndeg))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    1076                 :             : 
    1077         [ +  + ]:          31 :  do iband=1,ndeg
    1078         [ +  + ]:          63 :    do jband=1,ndeg
    1079                 :             :      self%eig2_diag_cart(:,:, iband, jband) = one/two_pi**2 * &
    1080                 :             :        matmul(matmul(cryst%rprimd(:,:),eig2_diag(:,:, iband, jband)), &
    1081   [ +  +  +  +  :        4114 :        transpose(cryst%rprimd(:,:)))
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
             +  +  +  + ]
    1082                 :             :    enddo
    1083                 :             :  enddo
    1084                 :             : 
    1085                 :             :  ! Determine the type of the Fr\"ohlich model
    1086                 :             :  ! TODO: check if a material actually has cubic symmetry for kind = 3?
    1087         [ +  + ]:          13 :  if (ndeg == 1) then
    1088                 :             :    ! Standard or Anisotropic Fr\"ohlich model
    1089                 :          10 :    self%kind = 1
    1090                 :             : 
    1091                 :             :    ! Assuming the single band is parabolic in the three Cartesian directions
    1092         [ +  + ]:          40 :    unit_kdir(:, 1) = (/1, 0, 0/)
    1093         [ +  + ]:          40 :    unit_kdir(:, 2) = (/0, 1, 0/)
    1094         [ +  + ]:          40 :    unit_kdir(:, 3) = (/0, 0, 1/)
    1095                 :             : 
    1096         [ +  + ]:          40 :    do idir=1,3
    1097                 :             :      self%band_params(idir) = dot_product(unit_kdir(:, idir), &
    1098   [ +  +  -  +  :         670 :        matmul(self%eig2_diag_cart(:,:, 1, 1), unit_kdir(:, idir)))
          +  +  +  +  +  
             +  +  +  +  
                      - ]
    1099                 :             :    enddo
    1100                 :             : 
    1101         [ +  + ]:           3 :  else if (ndeg == 3) then
    1102                 :             :    ! Cubic generalized Fr\"ohlich model with triply degenerate bands
    1103                 :           2 :    self%kind = 2
    1104                 :             : 
    1105                 :             :    ! Symmety inequivalent cubic directions to obtain the Luttinger parameters
    1106         [ +  + ]:           8 :    unit_kdir(:, 1) = (/1, 0, 0/)
    1107         [ +  + ]:           8 :    unit_kdir(:, 2) = (/1, 1, 0/)/sqrt(2.0)
    1108         [ +  + ]:           8 :    unit_kdir(:, 3) = (/1, 1, 1/)/sqrt(3.0)
    1109                 :             : 
    1110                 :             :    ! Initialize the diagonalization routine
    1111                 :           2 :    lwork = -1
    1112   [ -  +  +  -  :           6 :    ABI_MALLOC(rwork, (3*ndeg - 2))
          +  -  -  +  -  
                      + ]
    1113         [ -  + ]:           2 :    ABI_MALLOC(work, (1))
    1114                 :             :    call zheev('V', 'U', ndeg, eigenvec(:,:), ndeg, eigenval, work(:), lwork, &
    1115                 :           2 :      rwork(:), info)
    1116                 :           2 :    lwork=int(work(1))
    1117                 :           2 :    ABI_FREE(work)
    1118   [ -  +  +  -  :           6 :    ABI_MALLOC(work, (lwork))
          +  -  +  -  -  
                +  -  + ]
    1119                 :             : 
    1120   [ +  +  +  + ]:          26 :    lutt_eigenval(:, :) = zero
    1121                 :             :    ! Inverse effective mass tensor in the symmetry inequivalent directions
    1122         [ +  + ]:           8 :    do idir=1,3
    1123                 :             : 
    1124         [ +  + ]:          24 :      do iband=1,ndeg
    1125         [ +  + ]:          78 :        do jband=1,ndeg
    1126                 :             :          lutt_eigenvec(iband, jband) = dot_product(unit_kdir(:, idir), &
    1127   [ +  +  -  +  :        1800 :            matmul(self%eig2_diag_cart(:, :, iband, jband), unit_kdir(:, idir)))
          +  -  +  -  +  
          -  -  +  -  +  
          +  +  +  +  +  
          +  +  -  +  -  
             +  +  +  - ]
    1128                 :             :        enddo
    1129                 :             :      enddo
    1130                 :             : 
    1131         [ +  + ]:          36 :      work(:) = zero
    1132         [ +  + ]:          48 :      rwork(:) = zero
    1133                 :             :      call zheev('V', 'U', ndeg, lutt_eigenvec(:,:), ndeg, &
    1134   [ +  -  +  +  :          42 :        lutt_eigenval(idir, :), work(:), lwork, rwork(:), info)
             +  -  +  + ]
    1135         [ -  + ]:           8 :      ABI_CHECK(info == 0, sjoin("zheev returned info: ", itoa(info)))
    1136                 :             :   enddo
    1137                 :             : 
    1138         [ -  + ]:           2 :   ABI_FREE(work)
    1139         [ -  + ]:           2 :   ABI_FREE(rwork)
    1140                 :             : 
    1141                 :             :   ! TODO: this looks ugly
    1142                 :             :   ! is there any better wa to analyze and set the Luttinger parameters?
    1143                 :             : 
    1144                 :             :   ! Check degeneracies in the (100) direction, get A and B luttinger params
    1145                 :             :   ! Inverse effective masses are: 2*A and 2*B (twofold)
    1146         [ +  - ]:           2 :   if (abs(lutt_eigenval(1, 2) - lutt_eigenval(1, 3)) < tol5) then
    1147                 :           2 :     self%band_params(1)=half*lutt_eigenval(1, 1)
    1148                 :           2 :     self%band_params(2)=half*half*(lutt_eigenval(1, 2) + lutt_eigenval(1, 3))
    1149         [ #  # ]:           0 :   else if (abs(lutt_eigenval(1, 2) - lutt_eigenval(1, 1)) < tol5) then
    1150                 :           0 :     self%band_params(1) = half*half*(lutt_eigenval(1, 2) + lutt_eigenval(1, 1))
    1151                 :           0 :     self%band_params(2) = half*lutt_eigenval(1, 3)
    1152                 :             :   else
    1153                 :           0 :     self%lutt_warn(1) = .true.
    1154                 :             :   endif
    1155                 :             : 
    1156                 :             :   ! Check degeneracies in the (111) direction, get C luttinger parameter
    1157                 :             :   ! Inverse effective masses are 2/3*(A + 2B - C) (twofold) and
    1158                 :             :   ! 2/3*(A + 2B + 2C)
    1159         [ +  - ]:           2 :   if (abs(lutt_eigenval(3, 2) - lutt_eigenval(3, 3)) < tol5) then
    1160                 :             :     self%band_params(3) = self%band_params(1) + 2*self%band_params(2) - &
    1161                 :           2 :       onehalf*half*(lutt_eigenval(3, 2) + lutt_eigenval(3, 3))
    1162         [ #  # ]:           0 :   else if (abs(lutt_eigenval(3, 2) - lutt_eigenval(3, 1)) < tol5) then
    1163                 :             :     self%band_params(3) = self%band_params(1) + 2*self%band_params(2) - &
    1164                 :           0 :       onehalf*half*(lutt_eigenval(3, 2) + lutt_eigenval(3, 1))
    1165                 :             :   else
    1166                 :           0 :     self%lutt_warn(2) = .true.
    1167                 :             :   endif
    1168                 :             : 
    1169                 :             :   ! Verifty that the (110) direction inverse effective masses are coherent
    1170                 :             :   ! with the Luttinger parameters: 2*B, A + B + C, A + B - C
    1171                 :           2 :   lutt_found(:) = .false.
    1172         [ +  + ]:           8 :   do ipar=1,ndeg
    1173         [ +  + ]:           8 :     if (abs(lutt_eigenval(2, ipar) - 2*self%band_params(2)) < tol4) then
    1174                 :           2 :       lutt_found(1) = .true.
    1175         [ +  + ]:           4 :     else if (abs(lutt_eigenval(2, ipar) - (self%band_params(1) + &
    1176                 :             :       self%band_params(2) - self%band_params(3))) < tol4) then
    1177                 :           2 :       lutt_found(2) = .true.
    1178         [ +  - ]:           2 :     else if (abs(lutt_eigenval(2, ipar) - (self%band_params(1) + &
    1179                 :             :       self%band_params(2) + self%band_params(3))) < tol4) then
    1180                 :           2 :       lutt_found(3) = .true.
    1181                 :             :     endif
    1182                 :             :   enddo
    1183                 :             : 
    1184   [ +  +  +  -  :           8 :   if (.not. (all(lutt_found))) self%lutt_warn(3) = .true.
                   -  + ]
    1185                 :             : 
    1186                 :             :  else
    1187                 :             :    ! Generalized Fr\"ohlich model
    1188                 :           1 :    self%kind = 0
    1189                 :             :  endif
    1190                 :             : 
    1191                 :             :  ! The electronic subspace has been initialized
    1192                 :          13 :  self%isinitel = .true.
    1193                 :             : 
    1194                 :          13 : end subroutine frohlich_init_el
    1195                 :             : !!***
    1196                 :             : 
    1197                 :             : 
    1198                 :             : !!****f* m_frohlich/frohlich_init_ph
    1199                 :             : !! NAME
    1200                 :             : !!  frohlich_init_ph
    1201                 :             : !!
    1202                 :             : !! FUNCTION
    1203                 :             : !!  Description
    1204                 :             : !!
    1205                 :             : !! INPUTS
    1206                 :             : !!  self<frohlich_t> = Datatype gathering information on the Fr\"ohlich model
    1207                 :             : !!  cryst<crystal_t> = Structure defining the unit cell
    1208                 :             : !!    %natom = number of atoms in the unit cell
    1209                 :             : !!    %ucvol = real space unit cell volume
    1210                 :             : !!  efmas_ntheta = number of points required for spherical integration used
    1211                 :             : !!  to obtain the effective mass tensor [Laflamme2016]
    1212                 :             : !!  ifc<ifc_type> = Dynamical matrix and interatomic force constants
    1213                 :             : !!
    1214                 :             : !! OUTPUT
    1215                 :             : !!  self<frohlich_t> = Datatype gathering information on the Fr\"ohlich model
    1216                 :             : !!
    1217                 :             : !! SOURCE
    1218                 :             : 
    1219                 :           3 : subroutine frohlich_init_ph(self, cryst, efmas_ntheta, ifc)
    1220                 :             : 
    1221                 :             : !Arguments ------------------------------------
    1222                 :             : !scalars
    1223                 :             :  class(frohlich_t), intent(inout) :: self
    1224                 :             :  type(crystal_t), intent(in) :: cryst
    1225                 :             :  type(ifc_type), intent(in) :: ifc
    1226                 :             :  integer, intent(in) :: efmas_ntheta
    1227                 :             : !arrays
    1228                 :             : 
    1229                 :             : !Local variables-------------------------------
    1230                 :             : !scalars
    1231                 :             :  integer :: ntheta, nphi, nqdir
    1232                 :             :  integer :: iphi, itheta, iqdir, nu
    1233                 :             : ! integer :: ikpt, ideg, iband, jband
    1234                 :             : ! integer :: ndeg
    1235                 :             :  real(dp) :: weight
    1236                 :             :  real(dp) :: weight_phi, phi_radians
    1237                 :             :  real(dp) :: costheta, sintheta, cosphi, sinphi
    1238                 :             : !arrays
    1239                 :             : ! real(dp) :: kpt(3)
    1240                 :           3 :  real(dp), allocatable :: gq_points_theta(:), gq_weights_theta(:)
    1241                 :           3 :  real(dp), allocatable :: gq_points_cosphi(:), gq_points_sinphi(:)
    1242                 :             : 
    1243                 :             : ! *************************************************************************
    1244                 :             : 
    1245                 :           3 :  self%natom = cryst%natom
    1246                 :           3 :  self%ucvol = cryst%ucvol
    1247   [ +  +  +  + ]:          39 :  self%gmet(:,:) = cryst%gmet(:,:)
    1248                 :             : 
    1249                 :             :  ! Initialization of integrals
    1250                 :             :  ! This part allocates and initializes arrays unit_qdir(3,nqdir) and
    1251                 :             :  ! weights_qdir(nqdir) used for spherical integration over q-points directions
    1252                 :           3 :  ntheta = efmas_ntheta
    1253                 :           3 :  nphi = 2*ntheta
    1254                 :           3 :  nqdir = nphi*ntheta
    1255                 :             : 
    1256   [ -  +  +  -  :           9 :  ABI_MALLOC(gq_points_theta, (ntheta))
          +  -  +  -  -  
                +  -  + ]
    1257   [ -  +  +  -  :           6 :  ABI_MALLOC(gq_weights_theta, (ntheta))
             -  +  -  + ]
    1258   [ -  +  +  -  :           9 :  ABI_MALLOC(gq_points_cosphi, (nphi))
          +  -  +  -  -  
                +  -  + ]
    1259   [ -  +  +  -  :           6 :  ABI_MALLOC(gq_points_sinphi, (nphi))
             -  +  -  + ]
    1260                 :             : 
    1261                 :           3 :  self%nqdir = nqdir
    1262   [ -  +  +  -  :           9 :  ABI_MALLOC(self%unit_qdir, (3, nqdir))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    1263   [ -  +  +  -  :           9 :  ABI_MALLOC(self%weights_qdir, (nqdir))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    1264                 :             : 
    1265                 :           3 :  call cgqf(ntheta, 1, zero, zero, zero, pi, gq_points_theta, gq_weights_theta)
    1266                 :           3 :  weight_phi = two*pi/real(nphi, dp)
    1267                 :             : 
    1268         [ +  + ]:         603 :  do iphi=1,nphi
    1269                 :         600 :    phi_radians = weight_phi * (iphi-1)
    1270                 :         600 :    gq_points_cosphi(iphi) = cos(phi_radians)
    1271                 :         603 :    gq_points_sinphi(iphi) = sin(phi_radians)
    1272                 :             :  enddo
    1273                 :             : 
    1274                 :           3 :  nqdir = 0
    1275         [ +  + ]:         303 :  do itheta=1,ntheta
    1276                 :         300 :    costheta = cos(gq_points_theta(itheta))
    1277                 :         300 :    sintheta = sin(gq_points_theta(itheta))
    1278                 :         300 :    weight = gq_weights_theta(itheta)*weight_phi*sintheta
    1279                 :             : 
    1280         [ +  + ]:       60303 :    do iphi=1,nphi
    1281                 :       60000 :      cosphi = gq_points_cosphi(iphi)
    1282                 :       60000 :      sinphi = gq_points_sinphi(iphi)
    1283                 :       60000 :      nqdir = nqdir + 1
    1284                 :             : 
    1285                 :       60000 :      self%unit_qdir(1, nqdir) = sintheta*cosphi
    1286                 :       60000 :      self%unit_qdir(2, nqdir) = sintheta*sinphi
    1287                 :       60000 :      self%unit_qdir(3, nqdir) = costheta
    1288                 :       60300 :      self%weights_qdir(nqdir) = weight
    1289                 :             :    enddo
    1290                 :             :  enddo
    1291                 :             : 
    1292         [ -  + ]:           3 :  ABI_FREE(gq_points_theta)
    1293         [ -  + ]:           3 :  ABI_FREE(gq_weights_theta)
    1294         [ -  + ]:           3 :  ABI_FREE(gq_points_cosphi)
    1295         [ -  + ]:           3 :  ABI_FREE(gq_points_sinphi)
    1296                 :             : 
    1297                 :             :  ! Initialization of the generalized Fr\"ohlich parameters
    1298                 :             : 
    1299   [ -  +  +  -  :           9 :  ABI_MALLOC(self%dielt_qdir, (nqdir))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    1300   [ +  -  -  +  :          12 :  ABI_MALLOC(self%phfreq_qdir, (3*self%natom, nqdir))
          +  -  -  +  +  
          -  +  -  +  -  
          -  +  -  +  -  
                      + ]
    1301   [ -  +  +  -  :          12 :  ABI_MALLOC(self%polarity_qdir, (3, 3*self%natom, nqdir))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    1302   [ -  +  +  -  :           9 :  ABI_MALLOC(self%proj_polarity_qdir, (3*self%natom, nqdir))
          -  +  +  -  -  
             +  -  +  -  
                      + ]
    1303   [ -  +  +  -  :           9 :  ABI_MALLOC(self%investar, (3*self%natom, nqdir))
          -  +  +  -  -  
             +  -  +  -  
                      + ]
    1304   [ -  +  +  -  :           9 :  ABI_MALLOC(self%dielavg, (3*self%natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    1305   [ -  +  +  -  :           9 :  ABI_MALLOC(self%isiractive, (3*self%natom))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    1306                 :             : 
    1307                 :             :  ! Phonon frequencies and mode polarity vectors for each q-vector direction
    1308                 :             :  call ifc%calcnwrite_nana_terms(cryst, nqdir, self%unit_qdir(:,:), &
    1309                 :           3 :    phfrq2l=self%phfreq_qdir, polarity2l=self%polarity_qdir)
    1310                 :             : 
    1311                 :             :  ! High-frequency dielectric constant for each q-vector direction
    1312         [ +  + ]:       60003 :  do iqdir=1,nqdir
    1313                 :             :    self%dielt_qdir(iqdir) = dot_product(self%unit_qdir(:, iqdir), &
    1314   [ +  +  +  +  :      960003 :      matmul(ifc%dielt(:,:), self%unit_qdir(:, iqdir)))
             +  -  +  + ]
    1315                 :             :  enddo
    1316                 :             : 
    1317   [ +  +  +  + ]:      480003 :  self%investar(:,:) = zero
    1318         [ +  + ]:          24 :  self%dielavg(:) = zero
    1319                 :             :  ! Prjections of mode polarities on unit q-vectors,
    1320                 :             :  ! inverse effective dielectric constants for each mode and q-vector directions
    1321                 :             :  ! and dielectric average over q-vectors (Eqs. (22), (26) of [deMelo2023])
    1322         [ +  + ]:       60003 :  do iqdir=1,nqdir
    1323         [ +  + ]:      300003 :    do nu=4,3*self%natom
    1324                 :             :      self%proj_polarity_qdir(nu, iqdir) = &
    1325         [ +  + ]:      960000 :        dot_product(self%unit_qdir(:, iqdir), self%polarity_qdir(:, nu, iqdir))
    1326                 :             : 
    1327                 :             :      self%investar(nu, iqdir) = (self%proj_polarity_qdir(nu, iqdir) / &
    1328                 :             :        self%dielt_qdir(iqdir) / self%phfreq_qdir(nu, iqdir))**2 * &
    1329                 :      240000 :        four*pi/self%ucvol
    1330                 :             : 
    1331                 :             :      self%dielavg(nu) = self%dielavg(nu) + (self%weights_qdir(iqdir) * &
    1332                 :      300000 :        self%investar(nu, iqdir)*sqrt(self%phfreq_qdir(nu, iqdir)))
    1333                 :             :    enddo
    1334                 :             :  enddo
    1335         [ +  + ]:          24 :  self%dielavg(:) = sqrthalf*quarter*piinv * self%dielavg(:)
    1336                 :             : 
    1337         [ +  + ]:          24 :  self%isiractive(:) = .false.
    1338                 :             :  ! Check for the infrared-active phonon modes: dielectric average is non-zero
    1339         [ +  + ]:          15 :  do nu=4,3*self%natom
    1340         [ +  + ]:          15 :    if (self%dielavg(nu) > tol10) self%isiractive(nu) = .true.
    1341                 :             :  enddo
    1342                 :             : 
    1343                 :             :  ! Rough correction for the ZPR in the infrared limit of the Fr\"ohlich model
    1344                 :           3 :  self%zpr_gamma = zero
    1345         [ +  + ]:          15 :  do nu=4,3*self%natom
    1346         [ +  + ]:      240015 :    do iqdir=1,self%nqdir
    1347                 :             :      self%zpr_gamma = self%zpr_gamma + &
    1348                 :      240012 :        self%investar(nu, iqdir)*self%weights_qdir(iqdir)
    1349                 :             :    enddo
    1350                 :             :  enddo
    1351                 :             : !Do not remove this useless line: a bug in the ifx2025 compiler is avoided thanks to it ...
    1352                 :           3 :  write(std_out,'(a,es16.6)')' frohlich_init_ph : after the loop, self%zpr_gamma=',self%zpr_gamma
    1353                 :           3 :  self%zpr_gamma = quarter*piinv*self%zpr_gamma
    1354                 :           3 :  self%zpr_gamma = two*(three*quarter*piinv/self%ucvol)**third * self%zpr_gamma
    1355                 :             : 
    1356                 :             :  ! The phonon subspace has been initialized
    1357                 :           3 :  self%isinitph = .true.
    1358                 :             : 
    1359                 :           3 : end subroutine frohlich_init_ph
    1360                 :             : !!***
    1361                 :             : 
    1362                 :             : 
    1363                 :             : !!****f* m_frohlich/mat3inv
    1364                 :             : !! NAME
    1365                 :             : !!  mat3inv
    1366                 :             : !!
    1367                 :             : !! FUNCTION
    1368                 :             : !!  Inverts a 3x3 matrix of real elements
    1369                 :             : !!
    1370                 :             : !! INPUTS
    1371                 :             : !!  mm(3, 3) = real matrix to be inverted
    1372                 :             : !!
    1373                 :             : !! OUTPUT
    1374                 :             : !!  mit(3, 3) = inverse of the input matrix
    1375                 :             : !!
    1376                 :             : !! SOURCE
    1377                 :             : 
    1378                 :    54540000 : subroutine mat3inv(mm, mit)
    1379                 :             : 
    1380                 :             : !Arguments ------------------------------------
    1381                 :             : !arrays
    1382                 :             :  real(dp), intent(in) :: mm(3, 3)
    1383                 :             :  real(dp), intent(out) :: mit(3, 3)
    1384                 :             : 
    1385                 :             : !Local variables-------------------------------
    1386                 :             : !scalars
    1387                 :             :  real(dp) :: dd
    1388                 :             :  character(len=500) :: msg
    1389                 :             : !arrays
    1390                 :             :  real(dp) :: tt(3, 3)
    1391                 :             : 
    1392                 :             : ! *************************************************************************
    1393                 :             : 
    1394                 :             :  ! Minors and determinant
    1395                 :    54540000 :  tt(1, 1) = mm(2, 2)*mm(3, 3) - mm(3, 2)*mm(2, 3)
    1396                 :    54540000 :  tt(1, 2) = mm(1, 3)*mm(3, 2) - mm(1, 2)*mm(3, 3)
    1397                 :    54540000 :  tt(1, 3) = mm(1, 2)*mm(2, 3) - mm(1, 3)*mm(2, 2)
    1398                 :    54540000 :  tt(2, 1) = mm(2, 3)*mm(3, 1) - mm(2, 1)*mm(3, 3)
    1399                 :    54540000 :  tt(2, 2) = mm(1, 1)*mm(3, 3) - mm(3, 1)*mm(1, 3)
    1400                 :    54540000 :  tt(2, 3) = mm(1, 3)*mm(2, 1) - mm(1, 1)*mm(2, 3)
    1401                 :    54540000 :  tt(3, 1) = mm(2, 1)*mm(3, 2) - mm(2, 2)*mm(3, 1)
    1402                 :    54540000 :  tt(3, 2) = mm(1, 2)*mm(3, 1) - mm(1, 1)*mm(3, 2)
    1403                 :    54540000 :  tt(3, 3) = mm(1, 1)*mm(2, 2) - mm(2, 1)*mm(1, 2)
    1404                 :             : 
    1405                 :    54540000 :  dd = mm(1, 1)*tt(1, 1) + mm(2, 1)*tt(2, 1) + mm(3, 1)*tt(3, 1)
    1406                 :             : 
    1407                 :             :  ! Make sure the matrix is not singular
    1408         [ +  - ]:    54540000 :  if (dd /=0) then
    1409   [ +  +  +  + ]:   709020000 :    mit(:,:) = tt(:,:) / dd
    1410                 :             :  else
    1411                 :           0 :    write(msg, '(2a,2x,9(i0,1x),a)') 'Attempting to invert real array',ch10, &
    1412                 :           0 :      mm,' ==> determinant is zero.'
    1413                 :           0 :    ABI_ERROR(msg)
    1414                 :             :  endif
    1415                 :             : 
    1416                 :    54540000 : end subroutine mat3inv
    1417                 :             : !!***
    1418                 :             : 
    1419                 :             : 
    1420                 :             : !!****f* m_frohlich/lk_hamiltonian
    1421                 :             : !! NAME
    1422                 :             : !!  lk_hamiltonian
    1423                 :             : !!
    1424                 :             : !! FUNCTION
    1425                 :             : !!  Construct a Luttinger-Kohn Hamiltonian at a given k-point for a set of the
    1426                 :             : !! Luttinger-Kohn parameters A, B, C
    1427                 :             : !!
    1428                 :             : !! INPUTS
    1429                 :             : !!  band_params(3) = Luttinger-Kohn parameters A, B, C
    1430                 :             : !!  kpt(3) = wavevector at which the Hamiltonian is obtained (dimensional)
    1431                 :             : !!
    1432                 :             : !! OUTPUT
    1433                 :             : !!  h_lk(3, 3) = Luttingher-Kohn Hamiltonian, H(k)
    1434                 :             : !!
    1435                 :             : !! SOURCE
    1436                 :             : 
    1437                 :    54540009 : subroutine lk_hamiltonian(band_params, kpt, h_lk)
    1438                 :             : 
    1439                 :             : !Arguments ------------------------------------
    1440                 :             : !arrays
    1441                 :             :  real(dp), intent(in) :: band_params(3)
    1442                 :             :  real(dp), intent(in) :: kpt(3)
    1443                 :             :  real(dp), intent(out) :: h_lk(3, 3)
    1444                 :             : 
    1445                 :             : ! *************************************************************************
    1446                 :             : 
    1447                 :    54540009 :  h_lk(1, 1) = band_params(1)*kpt(1)**2 + band_params(2)*(kpt(2)**2 + kpt(3)**2)
    1448                 :    54540009 :  h_lk(2, 2) = band_params(1)*kpt(2)**2 + band_params(2)*(kpt(1)**2 + kpt(3)**2)
    1449                 :    54540009 :  h_lk(3, 3) = band_params(1)*kpt(3)**2 + band_params(2)*(kpt(1)**2 + kpt(2)**2)
    1450                 :    54540009 :  h_lk(1, 2) = band_params(3)*kpt(1)*kpt(2)
    1451                 :    54540009 :  h_lk(1, 3) = band_params(3)*kpt(1)*kpt(3)
    1452                 :    54540009 :  h_lk(2, 3) = band_params(3)*kpt(2)*kpt(3)
    1453                 :             :  ! Symmetric matrix
    1454                 :    54540009 :  h_lk(2, 1) = h_lk(1, 2)
    1455                 :    54540009 :  h_lk(3, 1) = h_lk(1, 3)
    1456                 :    54540009 :  h_lk(3, 2) = h_lk(2, 3)
    1457                 :             : 
    1458                 :    54540009 : end subroutine lk_hamiltonian
    1459                 :             : !!***
    1460                 :             : 
    1461   [ -  +  #  #  :    55180084 : end module m_frohlich
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    1462                 :             : !!***
        

Generated by: LCOV version 2.3-1