LCOV - code coverage report
Current view: top level - src/72_response - m_efmas.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 96.6 % 955 923
Test Date: 2026-09-20 15:27:41 Functions: 100.0 % 12 12

            Line data    Source code
       1              : !!****m* ABINIT/m_efmas
       2              : !! NAME
       3              : !! m_efmas
       4              : !!
       5              : !! FUNCTION
       6              : !! This module contains datatypes for efmas functionalities.
       7              : !!
       8              : !! COPYRIGHT
       9              : !! Copyright (C) 2001-2026 ABINIT group (JLJ)
      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_efmas
      23              : 
      24              :  use defs_basis
      25              :  use m_errors
      26              :  use m_abicore
      27              :  use netcdf
      28              :  use m_efmas_defs
      29              :  use m_nctk
      30              :  use m_cgtools
      31              :  use m_dtset
      32              : 
      33              :  use defs_abitypes,         only : MPI_type
      34              :  use m_gaussian_quadrature, only : cgqf
      35              :  use m_io_tools, only : get_unit
      36              : 
      37              :  implicit none
      38              : 
      39              :  private
      40              : 
      41              : !public procedures.
      42              :  public :: efmasval_free
      43              :  public :: efmasval_free_array
      44              :  public :: efmasdeg_free
      45              :  public :: efmasdeg_free_array
      46              :  public :: efmas_ncread
      47              :  public :: check_degeneracies
      48              :  public :: print_tr_efmas
      49              :  public :: print_efmas
      50              :  public :: efmas_main
      51              :  public :: efmas_analysis
      52              : 
      53              : !private procedures.
      54              :  private :: MATMUL_ ! Workaround to make tests pass on ubu/buda slaves
      55              :  interface MATMUL_
      56              :   module procedure MATMUL_DP
      57              :   module procedure MATMUL_DPC
      58              :  end interface MATMUL_
      59              : 
      60              : !!***
      61              : 
      62              : CONTAINS
      63              : 
      64              : !===========================================================
      65              : 
      66              : !!****f* m_efmas/efmasval_free
      67              : !! NAME
      68              : !! efmasval_free
      69              : !!
      70              : !! FUNCTION
      71              : !! This routine deallocates an efmasval_type.
      72              : !!
      73              : !! INPUTS
      74              : !!
      75              : !! OUTPUT
      76              : !!
      77              : !! SOURCE
      78              : 
      79          398 : subroutine efmasval_free(efmasval)
      80              : 
      81              :  !Arguments ------------------------------------
      82              :  type(efmasval_type),intent(inout) :: efmasval
      83              :  ! *********************************************************************
      84              : 
      85          398 :  ABI_SFREE(efmasval%ch2c)
      86          398 :  ABI_SFREE(efmasval%eig2_diag)
      87              : 
      88          398 : end subroutine efmasval_free
      89              : !!***
      90              : 
      91              : !----------------------------------------------------------------------
      92              : 
      93              : !!****f* ABINIT/efmasval_free_array
      94              : !! NAME
      95              : !! efmasval_free_array
      96              : !!
      97              : !! FUNCTION
      98              : !! This routine deallocates an efmasval_type or, optionally, an array of efmasval_type.
      99              : !!
     100              : !! INPUTS
     101              : !!
     102              : !! OUTPUT
     103              : !!
     104              : !! SOURCE
     105              : 
     106          719 : subroutine efmasval_free_array(efmasval)
     107              : 
     108              :  !Arguments ------------------------------------
     109              :  type(efmasval_type),allocatable,intent(inout) :: efmasval(:,:)
     110              : 
     111              :  !!!Local variables-------------------------------
     112              :  integer :: i,j,n(2)
     113              : 
     114              :  ! *********************************************************************
     115              : 
     116              :  !XG20180810: please do not remove. Otherwise, I get an error on my Mac.
     117              :  !write(std_out,*)' efmasval_free_array : enter '
     118              : 
     119          719 :  if(allocated(efmasval)) then
     120           60 :    n=shape(efmasval)
     121          292 :    do i=1,n(1)
     122          690 :      do j=1,n(2)
     123          670 :        call efmasval_free(efmasval(i,j))
     124              :      end do
     125              :    end do
     126          418 :    ABI_FREE(efmasval)
     127              :  end if
     128              : 
     129          719 : end subroutine efmasval_free_array
     130              : !!***
     131              : 
     132              : !----------------------------------------------------------------------
     133              : 
     134              : !!****f* m_efmas/efmasdeg_free
     135              : !! NAME
     136              : !! efmasdeg_free
     137              : !!
     138              : !! FUNCTION
     139              : !! This routine deallocates an efmasdeg_type.
     140              : !!
     141              : !! INPUTS
     142              : !!
     143              : !! OUTPUT
     144              : !!
     145              : !! SOURCE
     146              : 
     147           29 : subroutine efmasdeg_free(efmasdeg)
     148              : 
     149              :  !Arguments ------------------------------------
     150              :  type(efmasdeg_type),intent(inout) :: efmasdeg
     151              : 
     152              :  ! *********************************************************************
     153              : 
     154           29 :  ABI_SFREE(efmasdeg%degs_bounds)
     155           29 :  ABI_SFREE(efmasdeg%ideg)
     156              : 
     157           29 : end subroutine efmasdeg_free
     158              : !!***
     159              : 
     160              : !----------------------------------------------------------------------
     161              : 
     162              : !!****f* m_efmas/efmasdeg_free_array
     163              : !! NAME
     164              : !! efmasdeg_free_array
     165              : !!
     166              : !! FUNCTION
     167              : !! This routine deallocates an efmasdeg_type or, optionally, an array of efmasdeg_type.
     168              : !!
     169              : !! INPUTS
     170              : !!
     171              : !! OUTPUT
     172              : !!
     173              : !! SOURCE
     174              : 
     175          719 :  subroutine efmasdeg_free_array(efmasdeg)
     176              : 
     177              :  !Arguments ------------------------------------
     178              :  type(efmasdeg_type),allocatable,intent(inout) :: efmasdeg(:)
     179              : 
     180              :  !!!Local variables-------------------------------
     181              :  integer :: i,n
     182              : 
     183              :  ! *********************************************************************
     184          719 :  if(allocated(efmasdeg)) then
     185           20 :    n=size(efmasdeg)
     186           49 :    do i=1,n
     187           49 :      call efmasdeg_free(efmasdeg(i))
     188              :    end do
     189           49 :    ABI_FREE(efmasdeg)
     190              :  end if
     191              : 
     192          719 :  end subroutine efmasdeg_free_array
     193              : !!***
     194              : 
     195              : !----------------------------------------------------------------------
     196              : 
     197              : !!****f* m_efmas/check_degeneracies
     198              : !! NAME
     199              : !! check_degeneracies
     200              : !!
     201              : !! FUNCTION
     202              : !! This routine check for 0th order band degeneracies at given k-point.
     203              : !!
     204              : !! INPUTS
     205              : !!
     206              : !! OUTPUT
     207              : !!
     208              : !! SOURCE
     209              : 
     210           24 :  subroutine check_degeneracies(efmasdeg,bands,nband,eigen,deg_tol)
     211              : 
     212              :    !Arguments ------------------------------------
     213              :    type(efmasdeg_type),intent(out) :: efmasdeg
     214              :    integer,intent(in) :: bands(2),nband
     215              :    real(dp),intent(in) :: eigen(nband)
     216              :    real(dp),intent(in),optional :: deg_tol
     217              : 
     218              :    !!!Local variables-------------------------------
     219              :    integer :: deg_dim,iband, ideg
     220           24 :    integer, allocatable :: degs_bounds(:,:)
     221              :    real(dp) :: tol
     222           24 :    real(dp) :: eigen_tmp(nband)
     223              :    logical :: treated
     224              : 
     225              :    ! *********************************************************************
     226              : 
     227           24 :    tol=tol5; if(present(deg_tol)) tol=deg_tol
     228              : 
     229              :    !!! Determine sets of degenerate states in eigen0, i.e., at 0th order.
     230           24 :    efmasdeg%ndegs=1
     231           24 :    efmasdeg%nband=nband
     232           72 :    ABI_MALLOC(degs_bounds,(2,nband))
     233           72 :    ABI_MALLOC(efmasdeg%ideg, (nband))
     234         1038 :    degs_bounds=0; degs_bounds(1,1)=1
     235          362 :    efmasdeg%ideg=0; efmasdeg%ideg(1)=1
     236              : 
     237          362 :    eigen_tmp(:) = eigen(:)
     238              : 
     239          338 :    do iband=2,nband
     240          314 :      if (ABS(eigen_tmp(iband)-eigen_tmp(iband-1))>tol) then
     241          160 :        degs_bounds(2,efmasdeg%ndegs) = iband-1
     242          160 :        efmasdeg%ndegs=efmasdeg%ndegs+1
     243          160 :        degs_bounds(1,efmasdeg%ndegs) = iband
     244              :      end if
     245          338 :      efmasdeg%ideg(iband) = efmasdeg%ndegs
     246              :    end do
     247           24 :    degs_bounds(2,efmasdeg%ndegs)=nband
     248           72 :    ABI_MALLOC(efmasdeg%degs_bounds,(2,efmasdeg%ndegs))
     249          576 :    efmasdeg%degs_bounds(1:2,1:efmasdeg%ndegs) = degs_bounds(1:2,1:efmasdeg%ndegs)
     250           24 :    ABI_FREE(degs_bounds)
     251              : 
     252              :    !!! Determine if treated bands are part of a degeneracy at 0th order.
     253           72 :    efmasdeg%deg_range=0
     254           24 :    deg_dim=0
     255           24 :    treated=.false.
     256           24 :    write(std_out,'(a,i6)') 'Number of sets of bands for this k-point:',efmasdeg%ndegs
     257              :    write(std_out,'(a)') 'Set index; range of bands included in the set; is the set degenerate?(T/F); &
     258           24 : &                        is the set treated by EFMAS?(T/F):'
     259          208 :    do ideg=1,efmasdeg%ndegs
     260          184 :      deg_dim = efmasdeg%degs_bounds(2,ideg) - efmasdeg%degs_bounds(1,ideg) + 1
     261              :      !If there is some level in the set that is inside the interval defined by bands(1:2), treat such set
     262              :      !The band range might be larger than the nband interval: it includes it, and also include degenerate states
     263          184 :      if(efmasdeg%degs_bounds(1,ideg)<=bands(2) .and. efmasdeg%degs_bounds(2,ideg)>=bands(1)) then
     264           42 :        treated = .true.
     265           42 :        if(efmasdeg%degs_bounds(1,ideg)<=bands(1)) then
     266           24 :          efmasdeg%deg_range(1) = ideg
     267              :        end if
     268           42 :        if(efmasdeg%degs_bounds(2,ideg)>=bands(2)) then
     269           24 :          efmasdeg%deg_range(2) = ideg
     270              :        end if
     271              :      end if
     272          184 :      write(std_out,'(2i6,a,i6,2l4)') ideg, efmasdeg%degs_bounds(1,ideg), ' -', efmasdeg%degs_bounds(2,ideg), &
     273          392 : &                                    (deg_dim>1), treated
     274              :    end do
     275              : 
     276              : !   write(std_out,*)'ndegs=',          efmasdeg%ndegs
     277              : !   write(std_out,*)'degs_bounds=',    efmasdeg%degs_bounds
     278              : !   write(std_out,*)'ideg=',           efmasdeg%ideg
     279              : !   write(std_out,*)'deg_range=',      efmasdeg%deg_range
     280              : 
     281              :   !!This first attempt WORKS, but only if the symmetries are enabled, see line 1578 of dfpt_looppert.F90.
     282              :   !use m_crystal,          only : crystal_t, crystal_init, crystal_free, crystal_print
     283              :   !use m_esymm
     284              :   !integer :: timrev
     285              :   !character(len=132),allocatable :: title(:)
     286              :   !type(crystal_t) :: Cryst
     287              :   !type(esymm_t) :: Bsym
     288              : 
     289              :   !timrev = 1
     290              :   !if(dtset%istwfk(1)/=1) timrev=2
     291              :   !ABI_MALLOC(title,(dtset%ntypat))
     292              :   !title(:) = "Bloup"
     293              :   !call crystal_init(Cryst,dtset%spgroup,dtset%natom,dtset%npsp,dtset%ntypat,dtset%nsym,dtset%rprimd_orig(:,:,1),&
     294              :   !&                 dtset%typat,dtset%xred_orig(:,:,1),dtset%ziontypat,dtset%znucl,timrev,.false.,.false.,title,&
     295              :   !&                 dtset%symrel,dtset%tnons,dtset%symafm)
     296              :   !call crystal_print(Cryst)
     297              :   !ABI_FREE(title)
     298              :   !call esymm_init(Bsym,kpt_rbz(:,ikpt),Cryst,.false.,nspinor,1,mband,tol5,eigen0,dtset%tolsym)
     299              :   !write(std_out,*) 'DEBUG : Bsym. ndegs=',Bsym%ndegs
     300              :   !do iband=1,Bsym%ndegs
     301              :   !  write(std_out,*) Bsym%degs_bounds(:,iband)
     302              :   !end do
     303              : 
     304              :   !call crystal_free(Cryst)
     305              :   !call esymm_free(Bsym)
     306              : 
     307           24 :  end subroutine check_degeneracies
     308              : !!***
     309              : 
     310              : !----------------------------------------------------------------------
     311              : 
     312              : !!****f* m_efmas/print_efmas
     313              : !! NAME
     314              : !! print_efmas
     315              : !!
     316              : !! FUNCTION
     317              : !! This routine prints the information needed to compute rapidly the band effective masses,
     318              : !! namely, the generalized second-order k-derivatives of the eigenenergies,
     319              : !! see Eq.(66) of Laflamme2016.
     320              : !!
     321              : !! INPUTS
     322              : !!
     323              : !! OUTPUT
     324              : !!
     325              : !! SOURCE
     326              : 
     327           17 :  subroutine print_efmas(efmasdeg,efmasval,kpt,ncid)
     328              : 
     329              : !Arguments ------------------------------------
     330              : !scalars
     331              :  integer,            intent(in) :: ncid
     332              : !arrays
     333              :  real(dp),            intent(in) :: kpt(:,:)
     334              :  type(efmasdeg_type), intent(in) :: efmasdeg(:)
     335              :  type(efmasval_type), intent(in) :: efmasval(:,:)
     336              : 
     337              : !Local variables-------------------------------
     338              :  integer :: deg_dim,eig2_diag_arr_dim, ncerr
     339              :  integer :: iband,ideg,ideg_tot,ieig,ikpt
     340              :  integer :: jband,mband,ndegs_tot,nkpt,nkptdeg,nkptval
     341           17 :  integer, allocatable :: nband_arr(:), ndegs_arr(:), degs_range_arr(:,:)
     342           17 :  integer, allocatable :: ideg_arr(:,:), degs_bounds_arr(:,:)
     343           17 :  real(dp), allocatable :: ch2c_arr(:,:,:,:), eig2_diag_arr(:,:,:,:), max_abs_eigen1(:)
     344              :  character(len=500) :: msg
     345              : !----------------------------------------------------------------------
     346              : 
     347              : !XG20180519 Here, suppose that dtset%nkpt=nkpt_rbz (as done by Jonathan).
     348              : !To be reexamined/corrected at the time of parallelization.
     349              : 
     350           17 :  nkptdeg=size(efmasdeg,1)
     351           17 :  nkptval=size(efmasval,2)
     352           17 :  if(nkptdeg/=nkptval) then
     353            0 :    write(msg,'(a,i8,a,i8,a)') ' nkptdeg and nkptval =',nkptdeg,' and ',nkptval,' differ, which is inconsistent.'
     354            0 :    ABI_ERROR(msg)
     355              :  end if
     356           17 :  nkpt=nkptdeg
     357           17 :  if(nkpt/=size(kpt,2)) then
     358            0 :    write(msg,'(a,i8,a,i8,a)') ' nkptdeg and nkpt =',nkptdeg,' and ',nkpt,' differ, which is inconsistent.'
     359            0 :    ABI_ERROR(msg)
     360              :  end if
     361              : 
     362           17 :  mband=size(efmasval,1)
     363              : 
     364              : !Total number of (degenerate) sets over all k points
     365           41 :  ndegs_tot=sum(efmasdeg%ndegs)
     366              : !Total number of generalized second-order k-derivatives
     367              :  eig2_diag_arr_dim=zero
     368           41 :  do ikpt=1,nkpt
     369           83 :    do ideg=efmasdeg(ikpt)%deg_range(1),efmasdeg(ikpt)%deg_range(2)
     370           42 :      deg_dim = efmasdeg(ikpt)%degs_bounds(2,ideg) - efmasdeg(ikpt)%degs_bounds(1,ideg) + 1
     371           66 :      eig2_diag_arr_dim = eig2_diag_arr_dim + deg_dim**2
     372              :    enddo
     373              :  enddo
     374              : 
     375              : !Allocate the arrays to be nc-written
     376           51 :  ABI_MALLOC(nband_arr, (nkpt) )
     377           34 :  ABI_MALLOC(ndegs_arr, (nkpt) )
     378           51 :  ABI_MALLOC(degs_range_arr, (2,nkpt) )
     379           68 :  ABI_MALLOC(ideg_arr, (mband,nkpt) )
     380           51 :  ABI_MALLOC(degs_bounds_arr, (2,ndegs_tot) )
     381           51 :  ABI_MALLOC(ch2c_arr, (2,3,3,eig2_diag_arr_dim) )
     382           34 :  ABI_MALLOC(eig2_diag_arr, (2,3,3,eig2_diag_arr_dim) )
     383           51 :  ABI_MALLOC(max_abs_eigen1, (nkpt))
     384              : 
     385              : !Prepare the arrays to be nc-written
     386           17 :  ideg_tot=1
     387           17 :  ieig=1
     388           41 :  do ikpt=1,nkpt
     389           24 :    max_abs_eigen1(ikpt) = efmasdeg(ikpt)%max_abs_eigen1
     390           24 :    nband_arr(ikpt)=efmasdeg(ikpt)%nband
     391           24 :    ndegs_arr(ikpt)=efmasdeg(ikpt)%ndegs
     392           72 :    degs_range_arr(:,ikpt)=efmasdeg(ikpt)%deg_range(:)
     393          362 :    ideg_arr(:,ikpt)=0
     394          362 :    ideg_arr(1:efmasdeg(ikpt)%nband,ikpt)=efmasdeg(ikpt)%ideg(:)
     395          208 :    do ideg=1,efmasdeg(ikpt)%ndegs
     396          552 :      degs_bounds_arr(:,ideg_tot)=efmasdeg(ikpt)%degs_bounds(:,ideg)
     397          208 :      ideg_tot=ideg_tot+1
     398              :    enddo
     399           83 :    do ideg=efmasdeg(ikpt)%deg_range(1),efmasdeg(ikpt)%deg_range(2)
     400           42 :      deg_dim = efmasdeg(ikpt)%degs_bounds(2,ideg) - efmasdeg(ikpt)%degs_bounds(1,ideg) + 1
     401          145 :      do jband=1,deg_dim
     402          280 :        do iband=1,deg_dim
     403         2613 :          ch2c_arr(1,:,:,ieig+iband-1)=real(efmasval(ideg,ikpt)%ch2c(:,:,iband,jband))
     404         2613 :          ch2c_arr(2,:,:,ieig+iband-1)=aimag(efmasval(ideg,ikpt)%ch2c(:,:,iband,jband))
     405         2613 :          eig2_diag_arr(1,:,:,ieig+iband-1)=real(efmasval(ideg,ikpt)%eig2_diag(:,:,iband,jband))
     406         2692 :          eig2_diag_arr(2,:,:,ieig+iband-1)=aimag(efmasval(ideg,ikpt)%eig2_diag(:,:,iband,jband))
     407              :        enddo
     408          121 :        ieig=ieig+deg_dim
     409              :      enddo
     410              :    enddo
     411              :  enddo
     412              : 
     413              : !Define dimensions
     414              :  ncerr=nctk_def_dims(ncid, [ &
     415              : &  nctkdim_t("number_of_reduced_dimensions", 3), &
     416              : &  nctkdim_t("real_or_complex", 2), &
     417              : &  nctkdim_t("number_of_kpoints", nkpt), &
     418              : &  nctkdim_t("max_number_of_states", mband), &
     419              : &  nctkdim_t("total_number_of_degenerate_sets", ndegs_tot), &
     420              : &  nctkdim_t("eig2_diag_arr_dim", eig2_diag_arr_dim)&
     421          119 : &  ], defmode=.True.)
     422           17 :  NCF_CHECK(ncerr)
     423              : 
     424              :  ncerr = nctk_def_arrays(ncid, [ &
     425              : & nctkarr_t("reduced_coordinates_of_kpoints", "dp", "number_of_reduced_dimensions, number_of_kpoints"), &
     426              : & nctkarr_t("number_of_states", "int", "number_of_kpoints"), &
     427              : & nctkarr_t("number_of_degenerate_sets", "int", "number_of_kpoints"), &
     428              : & nctkarr_t("degs_range_arr", "int", "two, number_of_kpoints"), &
     429              : & nctkarr_t("ideg_arr", "int", "max_number_of_states, number_of_kpoints"), &
     430              : & nctkarr_t("degs_bounds_arr", "int", "two, total_number_of_degenerate_sets"), &
     431              : & nctkarr_t("max_abs_eigen1", "dp", "number_of_kpoints"), &
     432              : & nctkarr_t("ch2c_arr", "dp", "real_or_complex, number_of_reduced_dimensions, number_of_reduced_dimensions, eig2_diag_arr_dim"),  &
     433              : & nctkarr_t("eig2_diag_arr","dp","real_or_complex, number_of_reduced_dimensions, number_of_reduced_dimensions, eig2_diag_arr_dim")&
     434          170 :   ])
     435           17 :  NCF_CHECK(ncerr)
     436              : 
     437              :  ! Write data.
     438           17 :  NCF_CHECK(nctk_set_datamode(ncid))
     439           17 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "reduced_coordinates_of_kpoints"), kpt))
     440           17 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "number_of_states"), nband_arr))
     441           17 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "number_of_degenerate_sets"), ndegs_arr))
     442           17 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "degs_range_arr"),            degs_range_arr))
     443           17 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "ideg_arr"),                  ideg_arr))
     444           17 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "degs_bounds_arr"),           degs_bounds_arr))
     445           17 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "ch2c_arr"),                  ch2c_arr))
     446           17 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "eig2_diag_arr"),             eig2_diag_arr))
     447           17 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "max_abs_eigen1"),            max_abs_eigen1))
     448              : 
     449              : !Deallocate the arrays
     450           17 :  ABI_FREE(nband_arr)
     451           17 :  ABI_FREE(ndegs_arr)
     452           17 :  ABI_FREE(degs_range_arr)
     453           17 :  ABI_FREE(ideg_arr)
     454           17 :  ABI_FREE(degs_bounds_arr)
     455           17 :  ABI_FREE(ch2c_arr)
     456           17 :  ABI_FREE(eig2_diag_arr)
     457           17 :  ABI_FREE(max_abs_eigen1)
     458              : 
     459           17 : end subroutine print_efmas
     460              : !!***
     461              : 
     462              : !----------------------------------------------------------------------
     463              : 
     464              : !!****f* m_efmas/efmas_ncread
     465              : !! NAME
     466              : !! efmas_ncread
     467              : !!
     468              : !! FUNCTION
     469              : !! This routine reads from an EFMAS NetCDF file the information needed
     470              : !! to compute rapidly the band effective masses,
     471              : !! namely, the generalized second-order k-derivatives of the eigenenergies,
     472              : !! see Eq.(66) of Laflamme2016.
     473              : !!
     474              : !! INPUTS
     475              : !!
     476              : !! OUTPUT
     477              : !!
     478              : !! SOURCE
     479              : 
     480            3 :  subroutine efmas_ncread(efmasdeg,efmasval,kpt,ncid)
     481              : 
     482              : !Arguments ------------------------------------
     483              : !scalars
     484              :  integer,intent(in) :: ncid
     485              : !arrays
     486              :  real(dp), allocatable,intent(out) :: kpt(:,:)
     487              :  type(efmasdeg_type), allocatable, intent(out) :: efmasdeg(:)
     488              :  type(efmasval_type), allocatable, intent(out) :: efmasval(:,:)
     489              : 
     490              : !Local variables-------------------------------
     491              :  integer :: deg_dim,eig2_diag_arr_dim
     492              :  integer :: iband,ideg,ideg_tot,ieig,ikpt
     493              :  integer :: jband,mband,nband,ndegs,ndegs_tot,nkpt
     494            3 :  integer, allocatable :: nband_arr(:), ndegs_arr(:), degs_range_arr(:,:)
     495            3 :  integer, allocatable :: ideg_arr(:,:), degs_bounds_arr(:,:)
     496            3 :  real(dp), allocatable :: ch2c_arr(:,:,:,:), eig2_diag_arr(:,:,:,:), max_abs_eigen1(:)
     497              : !----------------------------------------------------------------------
     498              : 
     499            3 :  NCF_CHECK(nctk_set_datamode(ncid))
     500            3 :  NCF_CHECK(nctk_get_dim(ncid, "number_of_kpoints", nkpt))
     501            3 :  NCF_CHECK(nctk_get_dim(ncid, "max_number_of_states", mband))
     502            3 :  NCF_CHECK(nctk_get_dim(ncid, "total_number_of_degenerate_sets", ndegs_tot))
     503            3 :  NCF_CHECK(nctk_get_dim(ncid, "eig2_diag_arr_dim", eig2_diag_arr_dim))
     504              : 
     505              : !Allocate the arrays to be read from NetCDF file
     506            9 :  ABI_MALLOC(kpt, (3,nkpt) )
     507            9 :  ABI_MALLOC(nband_arr, (nkpt) )
     508            6 :  ABI_MALLOC(ndegs_arr, (nkpt) )
     509            9 :  ABI_MALLOC(degs_range_arr, (2,nkpt) )
     510           12 :  ABI_MALLOC(ideg_arr, (mband,nkpt) )
     511            9 :  ABI_MALLOC(degs_bounds_arr, (2,ndegs_tot) )
     512            9 :  ABI_MALLOC(ch2c_arr, (2,3,3,eig2_diag_arr_dim) )
     513            6 :  ABI_MALLOC(eig2_diag_arr, (2,3,3,eig2_diag_arr_dim) )
     514            9 :  ABI_MALLOC(max_abs_eigen1, (nkpt))
     515              : 
     516              : !Read from NetCDF file
     517            3 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "reduced_coordinates_of_kpoints"), kpt))
     518            3 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "number_of_states"), nband_arr))
     519            3 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "number_of_degenerate_sets"), ndegs_arr))
     520            3 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "degs_range_arr"),            degs_range_arr))
     521            3 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "ideg_arr"),                  ideg_arr))
     522            3 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "degs_bounds_arr"),           degs_bounds_arr))
     523            3 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "ch2c_arr"),                  ch2c_arr))
     524            3 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "eig2_diag_arr"),             eig2_diag_arr))
     525            3 :  NCF_CHECK(nf90_get_var(ncid, nctk_idname(ncid, "max_abs_eigen1"),            max_abs_eigen1))
     526              : 
     527              : !Prepare the efmas* datastructures
     528           14 :  ABI_MALLOC(efmasdeg,(nkpt))
     529           77 :  ABI_MALLOC(efmasval,(mband,nkpt))
     530              : 
     531            3 :  ideg_tot=1
     532            3 :  ieig=1
     533            8 :  do ikpt=1,nkpt
     534           15 :    efmasdeg(ikpt)%deg_range(:)=degs_range_arr(:,ikpt)
     535            5 :    nband=nband_arr(ikpt)
     536            5 :    efmasdeg(ikpt)%nband=nband
     537            5 :    efmasdeg(ikpt)%max_abs_eigen1 = max_abs_eigen1(ikpt)
     538           15 :    ABI_MALLOC(efmasdeg(ikpt)%ideg, (nband))
     539           70 :    efmasdeg(ikpt)%ideg=ideg_arr(1:nband,ikpt)
     540            5 :    ndegs=ndegs_arr(ikpt)
     541            5 :    efmasdeg(ikpt)%ndegs=ndegs
     542           15 :    ABI_MALLOC(efmasdeg(ikpt)%degs_bounds,(2,nband))
     543           53 :    do ideg=1,ndegs
     544          135 :      efmasdeg(ikpt)%degs_bounds(:,ideg)=degs_bounds_arr(:,ideg_tot)
     545           45 :      ideg_tot=ideg_tot+1
     546           50 :      if( efmasdeg(ikpt)%deg_range(1) <= ideg .and. ideg <= efmasdeg(ikpt)%deg_range(2) ) then
     547           13 :        deg_dim=efmasdeg(ikpt)%degs_bounds(2,ideg) - efmasdeg(ikpt)%degs_bounds(1,ideg) + 1
     548           52 :        ABI_MALLOC(efmasval(ideg,ikpt)%ch2c,(3,3,deg_dim,deg_dim))
     549           39 :        ABI_MALLOC(efmasval(ideg,ikpt)%eig2_diag,(3,3,deg_dim,deg_dim))
     550          447 :        efmasval(ideg,ikpt)%ch2c=zero
     551          447 :        efmasval(ideg,ikpt)%eig2_diag=zero
     552           31 :        do jband=1,deg_dim
     553           50 :          do iband=1,deg_dim
     554              :            efmasval(ideg,ikpt)%ch2c(:,:,iband,jband)=&
     555          416 : &           dcmplx(ch2c_arr(1,:,:,ieig+iband-1),ch2c_arr(2,:,:,ieig+iband-1))
     556              :            efmasval(ideg,ikpt)%eig2_diag(:,:,iband,jband)=&
     557          434 : &           dcmplx(eig2_diag_arr(1,:,:,ieig+iband-1),eig2_diag_arr(2,:,:,ieig+iband-1))
     558              :          enddo
     559           31 :          ieig=ieig+deg_dim
     560              :        enddo
     561              :      else
     562           32 :        ABI_MALLOC(efmasval(ideg,ikpt)%ch2c,(0,0,0,0))
     563           32 :        ABI_MALLOC(efmasval(ideg,ikpt)%eig2_diag,(0,0,0,0))
     564              :      end if
     565              :    end do
     566              :  enddo
     567              : 
     568              : !Deallocate the arrays
     569            3 :  ABI_FREE(nband_arr)
     570            3 :  ABI_FREE(ndegs_arr)
     571            3 :  ABI_FREE(degs_range_arr)
     572            3 :  ABI_FREE(ideg_arr)
     573            3 :  ABI_FREE(degs_bounds_arr)
     574            3 :  ABI_FREE(ch2c_arr)
     575            3 :  ABI_FREE(eig2_diag_arr)
     576            3 :  ABI_FREE(max_abs_eigen1)
     577              : 
     578            3 : end subroutine efmas_ncread
     579              : !!***
     580              : 
     581              : !----------------------------------------------------------------------
     582              : 
     583              : !!****f* m_efmas/print_tr_efmas
     584              : !! NAME
     585              : !! print_tr_efmas
     586              : !!
     587              : !! FUNCTION
     588              : !! This routine prints the transport equivalent effective mass and others info
     589              : !! for a degenerate set of bands
     590              : !!
     591              : !! INPUTS
     592              : !!
     593              : !! OUTPUT
     594              : !!
     595              : !! SOURCE
     596              : 
     597          188 :  subroutine print_tr_efmas(io_unit,kpt,band,deg_dim,mdim,ndirs,dirs,m_cart,rprimd,efmas_tensor,ntheta, &
     598          184 : &                       m_avg,m_avg_frohlich,saddle_warn,efmas_eigval,efmas_eigvec,transport_tensor_scale)
     599              : 
     600              :    !Arguments ------------------------------------
     601              :    integer, intent(in) :: io_unit, band, deg_dim, mdim, ndirs
     602              :    real(dp), intent(in) :: m_cart(ndirs,deg_dim), kpt(3), dirs(3,ndirs), rprimd(3,3), efmas_tensor(mdim,mdim,deg_dim)
     603              :    integer, intent(in) :: ntheta
     604              :    real(dp), intent(in) :: m_avg(deg_dim),m_avg_frohlich(deg_dim)
     605              :    logical, intent(in) :: saddle_warn(deg_dim)
     606              :    real(dp), intent(in), optional :: efmas_eigval(mdim,deg_dim)
     607              :    real(dp), intent(in), optional :: efmas_eigvec(mdim,mdim,deg_dim)
     608              :    real(dp), intent(in), optional :: transport_tensor_scale(deg_dim)
     609              : 
     610              :    !Local variables ------------------------------
     611              :    logical :: extras
     612              :    integer :: iband, adir
     613              :    character(len=22) :: format_eigvec
     614              :    character(len=500) :: msg, tmpstr
     615              :    real(dp) :: vec(3),mat(3,3)
     616              : 
     617           94 :    if(deg_dim>1) then
     618           36 :      extras = present(efmas_eigval) .and. present(efmas_eigvec)
     619           36 :      if(mdim==3 .and. .not. extras) then
     620            0 :        write(msg,'(a,l1,a,i1,a)') 'Subroutine print_tr_efmas called with degenerate=',deg_dim>1,&
     621            0 : &            ' and mdim=',mdim,', but missing required arguments for this case.'
     622            0 :        ABI_ERROR(msg)
     623              :      end if
     624           36 :      if(mdim==2 .and. .not. (extras .or. present(transport_tensor_scale))) then
     625            0 :        write(msg,'(a,l1,a,i1,a)') 'Subroutine print_tr_efmas called with degenerate=',deg_dim>1,&
     626            0 : &            ' and mdim=',mdim,', but missing required arguments for this case.'
     627            0 :        ABI_ERROR(msg)
     628              :      end if
     629              :    else
     630           58 :      extras = present(efmas_eigval) .and. present(efmas_eigvec)
     631           58 :      if(mdim>1 .and. .not. extras) then
     632            0 :        write(msg,'(a,l1,a,i1,a)') 'Subroutine print_tr_efmas called with degenerate=',deg_dim>1,&
     633            0 : &            ' and mdim=',mdim,', but missing required arguments for this case.'
     634            0 :        ABI_ERROR(msg)
     635              :      end if
     636              :    end if
     637              : 
     638           94 :    if(deg_dim>1) then
     639           36 :      write(io_unit,'(2a)') ch10,' COMMENTS: '
     640           36 :      write(io_unit,'(a,3(f6.3,a),i5,a,i5)') ' - At k-point (',kpt(1),',',kpt(2),',',kpt(3),'), bands ',band,' through ',&
     641           72 : &          band+deg_dim-1
     642           36 :      if(mdim>1) then
     643           34 :        write(io_unit,'(a)') '   are DEGENERATE (effective mass tensor is therefore not defined).'
     644           34 :        if(mdim==3) then
     645           32 :          write(io_unit,'(a)') '   See Section IIIB Eqs. (67)-(70) and Appendix E of PRB 93 205147 (2016).' ! [[cite:Laflamme2016]]
     646              :          write(io_unit,'(a,i7,a)') &
     647           32 : &          ' - Angular average effective mass for Frohlich model is to be averaged over degenerate bands. See later.'
     648            2 :        elseif(mdim==2) then
     649            2 :          write(io_unit,'(a)') ' - Also, 2D requested (perpendicular to Z axis).'
     650            2 :          write(io_unit,'(a)') '   See Section IIIB and Appendix F, Eqs. (F12)-(F14) of PRB 93 205147 (2016).' ! [[cite:Laflamme2016]]
     651              :        end if
     652           34 :        write(io_unit,'(a,i7,a)') ' - Associated theta integrals calculated with ntheta=',ntheta,' points.'
     653              :      else
     654            2 :        write(io_unit,'(a)') '   are DEGENERATE.'
     655            2 :        write(io_unit,'(a)') ' - Also, 1D requested (parallel to X axis).'
     656              :      end if
     657              :    end if
     658              : 
     659          238 :    if(ANY(saddle_warn)) then
     660           10 :      write(msg,'(2a)') ch10,'Band(s)'
     661           24 :      do iband=1,deg_dim
     662           24 :        if(saddle_warn(iband)) then
     663           14 :          write(tmpstr,'(i5)') band+iband-1
     664           14 :          msg = TRIM(msg)//' '//TRIM(tmpstr)//','
     665              :        end if
     666              :      end do
     667           10 :      write(tmpstr,'(6a)') ch10,'are not band extrema, but saddle points;',ch10, &
     668           10 : &                       'the transport equivalent formalism breaks down in these conditions.',ch10, &
     669           20 : &                       'The associated tensor(s) will therefore not be printed.'
     670           10 :      ABI_WARNING_UNIT(TRIM(msg)//TRIM(tmpstr), io_unit)
     671              :    end if
     672              : 
     673           94 :    if(deg_dim>1 .and. mdim>1) then
     674           34 :      write(msg,'(a)') ' Transport equivalent effective mass tensor'
     675              :    else
     676           60 :      write(msg,'(a)') ' Effective mass tensor'
     677              :    end if
     678              : 
     679           94 :    if(mdim>1) then
     680           92 :      write(format_eigvec,'(a,i1,a)') '(i3,',mdim,'f14.10,a,3f14.10)'
     681              :    end if
     682              : 
     683          252 :    do iband=1,deg_dim
     684          158 :      write(io_unit,'(2a,3(f6.3,a),i5)') ch10,' K-point (',kpt(1),',',kpt(2),',',kpt(3),') | band = ',band+iband-1
     685          158 :      write(io_unit,'(a)') trim(msg)//':'
     686          158 :      if(.not. saddle_warn(iband)) then
     687          556 :        do adir=1,mdim
     688          556 :          write(io_unit,'(3f26.10)') efmas_tensor(adir,:,iband)
     689              :        end do
     690          144 :        if(present(efmas_eigval))then
     691          138 :          write(io_unit,'(a)') trim(msg)//' eigenvalues:'
     692          138 :          write(io_unit,'(3f26.10)') efmas_eigval(:,iband)
     693              :        endif
     694              :      else
     695           14 :        write(io_unit,'(a)') '     *** SADDLE POINT: TRANSPORT EQV. EFF. MASS NOT DEFINED (see WARNING above) ***'
     696              :      end if
     697              : 
     698          158 :      if(mdim>1) then
     699          152 :        if(mdim==2 .and. deg_dim>1) then
     700            6 :          write(io_unit,'(a,f26.10)') 'Scaling of transport tensor (Eq. (FXX)) = ',transport_tensor_scale(iband)
     701              :        end if
     702          152 :        if(.not. saddle_warn(iband)) then
     703          138 :          if(io_unit == std_out) then
     704           69 :            write(io_unit,'(a)') trim(msg)//' eigenvectors in cartesian / reduced coord.:'
     705          272 :            do adir=1,mdim
     706          873 :              if( count( abs(efmas_eigval(adir,iband)-efmas_eigval(:,iband))<tol4 ) > 1 ) then
     707          132 :                write(io_unit,'(i3,a)') adir, ' Eigenvalue degenerate => eigenvector undefined'
     708              :              else
     709          284 :                vec=zero; vec(1:mdim)=efmas_eigvec(adir,:,iband)
     710          923 :                mat = transpose(rprimd)/two_pi
     711         1349 :                vec=matmul(mat,vec); vec=vec/sqrt(sum(vec**2))
     712           71 :                write(io_unit,format_eigvec) adir, efmas_eigvec(adir,:,iband), ' / ', vec
     713              :              end if
     714              :            end do
     715              :          end if
     716              :        end if
     717              :      end if
     718              : 
     719          158 :      if(mdim==3)then
     720              :        !An exactly zero average effective masse is artificial (or from a saddle point with symmetry). Does not print.
     721          144 :        if(abs(m_avg(iband))>tol8)then
     722              :          write(io_unit,'(a,f14.10)') &
     723          144 : &          ' Angular average effective mass 1/(<1/m>)= ',m_avg(iband)
     724              :        endif
     725          144 :        if(abs(m_avg_frohlich(iband))>tol8)then
     726              :          write(io_unit,'(a,f14.10)') &
     727          144 : &          ' Angular average effective mass for Frohlich model (<m**0.5>)**2= ',m_avg_frohlich(iband)
     728              :        endif
     729              :      endif
     730              : 
     731          158 :      write(io_unit,'(a)') ' Effective masses along directions: (cart. coord. / red. coord. -> eff. mass)'
     732          940 :      do adir=1,ndirs
     733         2752 :        vec=dirs(:,adir)
     734         8944 :        mat = transpose(rprimd)/two_pi
     735        13072 :        vec=matmul(mat,vec); vec=vec/sqrt(sum(vec**2))
     736          846 :        write(io_unit,'(i5,a,3f10.6,a,3f10.6,a,f14.10)') adir,': ', dirs(:,adir), ' / ', vec, ' -> ', m_cart(adir,iband)
     737              :      end do
     738              :    end do
     739              : 
     740           94 :    if(deg_dim>1 .and. mdim==3) then
     741           32 :      write(io_unit,'(2a)') ch10,&
     742           64 : &     ' Angular average effective mass for Frohlich model, averaged over degenerate bands.'
     743              :      write(io_unit,'(a,es16.6)') &
     744          120 : &     ' Value of     (<<m**0.5>>)**2 = ',(sum(abs(m_avg_frohlich(1:deg_dim))**0.5)/deg_dim)**2
     745              :      write(io_unit,'(a,es16.6,a)') &
     746          120 : &     ' Absolute Value of <<m**0.5>> = ', sum(abs(m_avg_frohlich(1:deg_dim))**0.5)/deg_dim,ch10
     747              :    endif
     748              : 
     749          186 :  end subroutine print_tr_efmas
     750              : !!***
     751              : 
     752              : !----------------------------------------------------------------------
     753              : 
     754              : !!****f* m_efmas/efmas_main
     755              : !! NAME
     756              : !! efmas_main
     757              : !!
     758              : !! FUNCTION
     759              : !! This routine calculates the generalized second-order k-derivative, Eq.66 of Laflamme2016,
     760              : !! in reduced coordinates.
     761              : !!
     762              : !! INPUTS
     763              : !!  cg(2,dtset%mpw*dtset%nspinor*dtset%mband*dtset%nsppol*nkpt_rbz)=pw coefficients of GS wavefunctions at k.
     764              : !!  cg1_pert(2,dtset%mpw*dtset%nspinor*dtset%mband*dtset%nsppo*nkpt_rbz,3,mpert) = first-order wf in G
     765              : !!            space for each perturbation. The wavefunction is orthogonal to the
     766              : !!            active space.
     767              : !!  dim_eig2rf = 1 if cg1_pert, gh0c1_pert and gh1c_pert are allocated.
     768              : !!               0 otherwise.
     769              : !!  dtset = dataset structure containing the input variable of the calculation.
     770              : !!  efmasdeg(nkpt_rbz) <type(efmasdeg_type)>= information about the band degeneracy at each k point
     771              : !!  eigen0(nkpt_rbz*dtset%mband*dtset%nsppol) = 0-order eigenvalues at all K-points:
     772              : !!            <k,n'|H(0)|k,n'> (hartree).
     773              : !!  eigen1(nkpt_rbz*2*dtset%nsppol*dtset%mband**2,3,mpert) = matrix of first-order:
     774              : !!            <k+Q,n'|H(1)|k,n> (hartree) (calculated in dfpt_cgwf).
     775              : !!  gh0c1_pert(2,dtset%mpw*dtset%nspinor*dtset%mband*dtset%nsppol*nkpt_rbz,3,mpert) = matrix containing the
     776              : !!            vector:  <G|H(0)|psi(1)>, for each perturbation.
     777              : !!  gh1c_pert(2,dtset%mpw*dtset%nspinor*dtset%mband*dtset%nsppol*nkpt_rbz,3,mpert)) = matrix containing the
     778              : !!            vector:  <G|H(1)|n,k>, for each perturbation. The wavefunction is
     779              : !!            orthogonal to the active space.
     780              : !!  istwfk_pert(nkpt_rbz,3,mpert) = integer for choice of storage of wavefunction at
     781              : !!            each k point for each perturbation.
     782              : !!  mpert = maximum number of perturbations.
     783              : !!  mpi_enreg = information about MPI parallelization.
     784              : !!  nkpt_rbz = number of k-points for each perturbation.
     785              : !!  npwarr(nkpt_rbz,mpert) = array of numbers of plane waves for each k-point
     786              : !!  rprimd(3,3)=dimensional primitive translations for real space (bohr)
     787              : !!
     788              : !! OUTPUT
     789              : !!
     790              : !! SIDE EFFECTS
     791              : !!  efmasval(mband,nkpt_rbz) <type(efmasdeg_type)>= generalized 2nd-order k-derivatives of eigenvalues
     792              : !!    efmasval(:,:)%ch2c INPUT : frozen wavefunction H2 contribution to generalized 2nd order k-derivatives of eigenenergy
     793              : !!    efmasval(:,:)%eig2_diag OUTPUT : generalized 2nd order k-derivatives of eigenenergy
     794              : !!
     795              : !! SOURCE
     796              : 
     797           17 :  subroutine efmas_main(cg,cg1_pert,dim_eig2rf,dtset,efmasdeg,efmasval,eigen0,&
     798           17 : &   eigen1,gh0c1_pert,gh1c_pert,istwfk_pert,mpert,mpi_enreg,nkpt_rbz,npwarr,rprimd)
     799              : 
     800              :  !Arguments ------------------------------------
     801              :  !scalars
     802              :   integer,            intent(in)    :: dim_eig2rf,mpert,nkpt_rbz
     803              :   type(dataset_type), intent(in)    :: dtset
     804              :   type(MPI_type),     intent(in) :: mpi_enreg
     805              :  !arrays
     806              :   integer,  intent(in) :: istwfk_pert(nkpt_rbz,3,mpert)
     807              :   integer,  intent(in) :: npwarr(nkpt_rbz,mpert)
     808              :   real(dp), intent(in) :: cg1_pert(2,dtset%mpw*dtset%nspinor*dtset%mband*dtset%nsppol*nkpt_rbz*dim_eig2rf,3,mpert)
     809              :   real(dp), intent(in) :: gh0c1_pert(2,dtset%mpw*dtset%nspinor*dtset%mband*dtset%nsppol*nkpt_rbz*dim_eig2rf,3,mpert)
     810              :   real(dp), intent(in) :: gh1c_pert(2,dtset%mpw*dtset%nspinor*dtset%mband*dtset%nsppol*nkpt_rbz*dim_eig2rf,3,mpert)
     811              :   real(dp), intent(in) :: eigen0(nkpt_rbz*dtset%mband*dtset%nsppol)
     812              :   real(dp), intent(in) :: eigen1(nkpt_rbz*2*dtset%nsppol*dtset%mband**2,3,mpert)
     813              :   real(dp), intent(in) :: rprimd(3,3)
     814              :   real(dp), intent(in) :: cg(2,dtset%mpw*dtset%nspinor*dtset%mband*dtset%nsppol*nkpt_rbz)
     815              :   type(efmasdeg_type), allocatable,intent(inout) :: efmasdeg(:)
     816              :   type(efmasval_type),  allocatable,intent(inout) :: efmasval(:,:)
     817              : 
     818              :  !Local variables-------------------------------
     819              :   logical :: degenerate, debug
     820              :   integer :: ipert, isppol
     821              :   integer :: icg2   !TODOM : Reactivate the sections for icg2 / allow choice of k-point other than the first in the list.
     822              :   integer :: npw_k, nband_k, nspinor, ideg, ikpt
     823              :   integer :: istwf_k, master,me,spaceworld
     824              :   integer :: band2tot_index,  bandtot_index, iband, jband, kband
     825              :   integer :: adir,bdir, deg_dim, degl
     826              :   character(len=500) :: msg
     827              :   real(dp) :: deltae, dot2i,dot2r,dot3i,dot3r,doti,dotr
     828           17 :   real(dp), allocatable :: cg0(:,:), cg1_pert2(:,:),cg1_pert1(:,:)
     829           17 :   real(dp), allocatable :: gh1c_pert2(:,:),gh1c_pert1(:,:),gh0c1_pert1(:,:)
     830              :   complex(dp) :: eig2_part(3,3), eig2_ch2c(3,3), eig2_paral(3,3), eig2_gauge_change(3,3)
     831              :   complex(dp) :: eig1a, eig1b, g_ch
     832           17 :   complex(dp), allocatable :: eigen1_deg(:,:), eig2_diag(:,:,:,:), eig2_diag_cart(:,:,:,:)
     833              : ! *********************************************************************
     834              : 
     835           17 :   debug = .false. ! Prints additional info to std_out
     836              : 
     837              : ! Init parallelism
     838           17 :   master =0
     839           17 :   spaceworld=mpi_enreg%comm_cell
     840           17 :   me=mpi_enreg%me_kpt
     841              : 
     842           17 :   write(msg,'(4a)') ch10,&
     843           17 : &  ' CALCULATION OF EFFECTIVE MASSES',ch10,&
     844           34 : &  ' NOTE : Additional infos (eff. mass eigenvalues, eigenvectors and, if degenerate, average mass) are available in stdout.'
     845           17 :   call wrtout(std_out,msg,'COLL')
     846           17 :   call wrtout(ab_out,msg,'COLL')
     847              : 
     848           17 :   if(dtset%nsppol/=1)then
     849            0 :     write(msg,'(a,i3,a)') 'nsppol=',dtset%nsppol,' is not yet treated in m_efmas.'
     850            0 :     ABI_ERROR(msg)
     851              :   end if
     852           17 :   if(dtset%nspden/=1)then
     853            0 :     write(msg,'(a,i3,a)') 'nspden=',dtset%nspden,' is not yet treated in m_efmas.'
     854            0 :     ABI_ERROR(msg)
     855              :   end if
     856           17 :   if(dtset%efmas_deg==0) then
     857            1 :     write(msg,'(a)') 'efmas_deg==0 is for debugging; the results for degenerate bands will be garbage.'
     858            1 :     ABI_WARNING(msg)
     859            1 :     ABI_WARNING_UNIT(msg, ab_out)
     860              :   end if
     861              : 
     862           17 :   ipert = dtset%natom+1
     863           17 :   isppol = 1
     864              : 
     865           17 :   icg2 = 0
     866           17 :   band2tot_index=0
     867           17 :   bandtot_index=0
     868              : 
     869              : 
     870              :   !XG20180519 : in the original coding by Jonathan, there is a lack of care about using dtset%nkpt or nkpt_rbz ...
     871              :   !Not important in the sequential case (?!) but likely problematic in the parallel case.
     872           41 :   do ikpt=1,dtset%nkpt
     873           24 :     npw_k = npwarr(ikpt,ipert)
     874           24 :     nband_k = dtset%nband(ikpt)
     875           24 :     nspinor = dtset%nspinor
     876           24 :     efmasdeg(ikpt)%max_abs_eigen1 = zero
     877              : 
     878           72 :     ABI_MALLOC(cg1_pert2,(2,npw_k*nspinor))
     879           48 :     ABI_MALLOC(cg1_pert1,(2,npw_k*nspinor))
     880           48 :     ABI_MALLOC(gh1c_pert2,(2,npw_k*nspinor))
     881           48 :     ABI_MALLOC(gh1c_pert1,(2,npw_k*nspinor))
     882           48 :     ABI_MALLOC(gh0c1_pert1,(2,npw_k*nspinor))
     883           48 :     ABI_MALLOC(cg0,(2,npw_k*nspinor))
     884              : 
     885           66 :     do ideg=efmasdeg(ikpt)%deg_range(1),efmasdeg(ikpt)%deg_range(2)
     886           42 :       deg_dim    = efmasdeg(ikpt)%degs_bounds(2,ideg) - efmasdeg(ikpt)%degs_bounds(1,ideg) + 1
     887           42 :       degenerate = (deg_dim>1) .and. (dtset%efmas_deg/=0)
     888           42 :       degl       = efmasdeg(ikpt)%degs_bounds(1,ideg)-1
     889              : 
     890          168 :       ABI_MALLOC(eigen1_deg,(deg_dim,deg_dim))
     891              :       !!! If treated band degenerate at 0th order, check that we are at extrema.
     892           42 :       if(degenerate) then
     893           72 :         do adir=1,3
     894          204 :           do iband=1,deg_dim
     895          672 :             do jband=1,deg_dim
     896              :               eigen1_deg(iband,jband) = cmplx(eigen1(2*(jband+degl)-1+(iband+degl-1)*2*nband_k,adir,ipert),&
     897          618 : &                                             eigen1(2*(jband+degl)  +(iband+degl-1)*2*nband_k,adir,ipert),dp)
     898              :             end do
     899              :           end do
     900              : 
     901          672 :           efmasdeg(ikpt)%max_abs_eigen1 = max(efmasdeg(ikpt)%max_abs_eigen1, maxval(abs(eigen1_deg)))
     902          690 :           if (.not.(ALL(ABS(eigen1_deg)<tol5))) then
     903            0 :             write(msg,'(a,a)') ' Effective masses calculations require given k-point(s) to be band extrema for given bands, ',&
     904            0 : &                              'but max abs gradient of band(s) was found to be greater than 1e-5. Abinit will continue anyway.'
     905            0 :             ABI_WARNING(TRIM(msg))
     906            0 :             ABI_WARNING(msg)
     907            0 :             ABI_WARNING_UNIT(msg, ab_out)
     908              :           end if
     909              :         end do !adir=1,3
     910              :       end if !degenerate(1)
     911           42 :       ABI_FREE(eigen1_deg)
     912              : 
     913          168 :       ABI_MALLOC(eig2_diag,(3,3,deg_dim,deg_dim))
     914          126 :       ABI_MALLOC(eig2_diag_cart,(3,3,deg_dim,deg_dim))
     915         2734 :       eig2_diag = zero
     916              : 
     917          121 :       do iband=1,deg_dim
     918           79 :         write(std_out,*)"  In the set (possibly degenerate) compute band ",iband  ! This line here to avoid weird
     919       136180 :         cg0(:,:) = cg(:,1+(degl+iband-1)*npw_k*nspinor+icg2:(degl+iband)*npw_k*nspinor+icg2)
     920          322 :         do jband=1,deg_dim
     921          201 :           eig2_part = zero
     922          201 :           eig2_ch2c = zero
     923          201 :           eig2_paral = zero
     924          201 :           eig2_gauge_change = zero
     925          804 :           do adir=1,3
     926          603 :             istwf_k = istwfk_pert(ikpt,adir,ipert)
     927         2613 :             do bdir=1,3
     928              : 
     929              :               ! Calculate the gauge change (to be subtracted to go from parallel transport to diagonal gauge).
     930        32130 :               do kband=1,nband_k
     931              :                 !!! Equivalent to the gauge change in eig2stern.F90, but works also for other choices than the parallel gauge.
     932              :                 eig1a = cmplx( eigen1(2*kband-1+(degl+iband-1)*2*nband_k+band2tot_index,adir,ipert), &
     933        30321 : &                -eigen1(2*kband+(degl+iband-1)*2*nband_k+band2tot_index,adir,ipert), kind=dp )
     934              :                 eig1b = cmplx( eigen1(2*kband-1+(degl+jband-1)*2*nband_k+band2tot_index,bdir,ipert), &
     935        30321 : &                eigen1(2*kband+(degl+jband-1)*2*nband_k+band2tot_index,bdir,ipert), kind=dp )
     936        30321 :                 g_ch = eig1a*eig1b
     937              :                 eig1a = cmplx( eigen1(2*kband-1+(degl+iband-1)*2*nband_k+band2tot_index,bdir,ipert), &
     938        30321 : &                -eigen1(2*kband+(degl+iband-1)*2*nband_k+band2tot_index,bdir,ipert), kind=dp )
     939              :                 eig1b = cmplx( eigen1(2*kband-1+(degl+jband-1)*2*nband_k+band2tot_index,adir,ipert), &
     940        30321 : &                eigen1(2*kband+(degl+jband-1)*2*nband_k+band2tot_index,adir,ipert), kind=dp )
     941        30321 :                 g_ch = g_ch + eig1a*eig1b
     942              : 
     943        30321 :                 deltae = eigen0(kband+bandtot_index) - eigen0((degl+iband)+bandtot_index)
     944        30321 :                 if( kband<=degl.or.kband>degl+deg_dim) then
     945        24372 :                   g_ch = g_ch/deltae
     946              :                 else
     947              :                   g_ch = zero
     948              :                 end if
     949        32130 :                 eig2_gauge_change(adir,bdir) = eig2_gauge_change(adir,bdir) + g_ch
     950              :               end do !kband
     951              : 
     952      2881710 :               cg1_pert2(:,:)   = cg1_pert(:,1+(degl+jband-1)*npw_k*nspinor+icg2:(degl+jband)*npw_k*nspinor+icg2,bdir,ipert)
     953      2881710 :               cg1_pert1(:,:)   = cg1_pert(:,1+(degl+iband-1)*npw_k*nspinor+icg2:(degl+iband)*npw_k*nspinor+icg2,adir,ipert)
     954      2881710 :               gh1c_pert1(:,:)  = gh1c_pert(:,1+(degl+iband-1)*npw_k*nspinor+icg2:(degl+iband)*npw_k*nspinor+icg2,adir,ipert)
     955      2881710 :               gh1c_pert2(:,:)  = gh1c_pert(:,1+(degl+jband-1)*npw_k*nspinor+icg2:(degl+jband)*npw_k*nspinor+icg2,bdir,ipert)
     956      2881710 :               gh0c1_pert1(:,:) = gh0c1_pert(:,1+(degl+iband-1)*npw_k*nspinor+icg2:(degl+iband)*npw_k*nspinor+icg2,adir,ipert)
     957              : 
     958              :               ! The first two dotprod corresponds to:  <Psi(1)|H(1)|Psi(0)> + cc.
     959              :               ! They are calculated using wavefunctions <Psi(1)| that are orthogonal to the active space.
     960              :               dotr=zero ; doti=zero
     961              :               call dotprod_g(dotr,doti,istwf_k,npw_k*nspinor,2,cg1_pert1,gh1c_pert2,mpi_enreg%me_g0,&
     962         1809 : &              mpi_enreg%comm_spinorfft)
     963              :               dot2r=zero ; dot2i=zero
     964              :               call dotprod_g(dot2r,dot2i,istwf_k,npw_k*nspinor,2,gh1c_pert1,cg1_pert2,mpi_enreg%me_g0,&
     965         1809 : &              mpi_enreg%comm_spinorfft)
     966              : 
     967              :               ! This dotprod corresponds to : <Psi(1)|H(0)- E(0)|Psi(1)>
     968              :               ! It is calculated using wavefunctions that are orthogonal to the active space.
     969              :               dot3r=zero ; dot3i=zero
     970              :               call dotprod_g(dot3r,dot3i,istwf_k,npw_k*nspinor,2,gh0c1_pert1,cg1_pert2,mpi_enreg%me_g0,&
     971         1809 : &              mpi_enreg%comm_spinorfft)
     972              : 
     973         1809 :               eig2_part(adir,bdir) = cmplx(dotr+dot2r+dot3r,doti+dot2i+dot3i,kind=dp)
     974              :               !eig2_part(adir,bdir) = cmplx(dotr+dot2r,doti+dot2i,kind=dp)  !DEBUG
     975              :               !eig2_part(adir,bdir) = cmplx(dotr,doti,kind=dp)              !DEBUG
     976              : 
     977         2412 :               eig2_ch2c(adir,bdir) = efmasval(ideg,ikpt)%ch2c(adir,bdir,iband,jband)
     978              : 
     979              :             end do !bdir
     980              :           end do  !adir
     981              : 
     982          804 :           do adir=1,3
     983         2613 :             do bdir=1,3
     984         2412 :               eig2_paral(adir,bdir) = eig2_part(adir,bdir) + eig2_part(bdir,adir) + eig2_ch2c(adir,bdir)
     985              :             end do
     986              :           end do
     987              : 
     988         2613 :           eig2_diag(:,:,iband,jband) = eig2_paral - eig2_gauge_change
     989         2613 :           efmasval(ideg,ikpt)%eig2_diag(:,:,iband,jband)=eig2_diag(:,:,iband,jband)
     990              : 
     991              :           !!! Decomposition of the hessian in into its different contributions.
     992              :           if(debug) then
     993              : 
     994              :             eig2_diag_cart(:,:,iband,jband) = matmul(matmul(rprimd,eig2_diag(:,:,iband,jband)),transpose(rprimd))/two_pi**2
     995              :             eig2_paral                 = matmul(matmul(rprimd,eig2_paral),                transpose(rprimd))/two_pi**2
     996              :             eig2_gauge_change          = matmul(matmul(rprimd,eig2_gauge_change),         transpose(rprimd))/two_pi**2
     997              :             eig2_ch2c                  = matmul(matmul(rprimd,eig2_ch2c),                 transpose(rprimd))/two_pi**2
     998              :             eig2_part                  = matmul(matmul(rprimd,eig2_part),                 transpose(rprimd))/two_pi**2
     999              : 
    1000              :             write(std_out,'(a)') 'Hessian of eigenvalues               = H. in parallel gauge - Gauge transformation'
    1001              :             do adir=1,3
    1002              :               write(std_out,'(3f12.8,2(a,3f12.8))')&
    1003              : &               real(eig2_diag_cart(adir,:,iband,jband),dp),' |',real(eig2_paral(adir,:),dp),' |',real(eig2_gauge_change(adir,:),dp)
    1004              :             end do
    1005              :             write(std_out,'(a)') 'H. in parallel gauge  = Second der. of H     + First derivatives    + First derivatives^T'
    1006              :             do adir=1,3
    1007              :               write(std_out,'(3f12.8,2(a,3f12.8))') real(eig2_paral(adir,:),dp),' |',real(eig2_ch2c(adir,:),dp),' |', &
    1008              : &                                                   real(eig2_part(adir,:),dp)
    1009              :             end do
    1010              :           end if !debug
    1011              : 
    1012          280 :           if(.not. degenerate .and. iband==jband) then
    1013           29 :             write(std_out,'(a,3f20.16)') 'Gradient of eigenvalues = ',&
    1014          493 : &            matmul(rprimd,eigen1(2*(degl+iband)-1+(degl+iband-1)*2*nband_k+band2tot_index,:,ipert))/two_pi
    1015              :           end if !.not.degenerate
    1016              : 
    1017              :         end do !jband
    1018              :       end do !iband
    1019              : 
    1020           42 :       ABI_FREE(eig2_diag)
    1021           66 :       ABI_FREE(eig2_diag_cart)
    1022              :     end do !ideg
    1023              : 
    1024           24 :     ABI_FREE(cg1_pert2)
    1025           24 :     ABI_FREE(cg1_pert1)
    1026           24 :     ABI_FREE(gh1c_pert2)
    1027           24 :     ABI_FREE(gh1c_pert1)
    1028           24 :     ABI_FREE(gh0c1_pert1)
    1029           24 :     ABI_FREE(cg0)
    1030              : 
    1031           24 :     icg2=icg2+npw_k*dtset%nspinor*nband_k
    1032           24 :     bandtot_index=bandtot_index+nband_k
    1033           41 :     band2tot_index=band2tot_index+2*nband_k**2
    1034              :   end do ! ikpt
    1035              : 
    1036           17 :  end subroutine efmas_main
    1037              : !!***
    1038              : 
    1039              : !----------------------------------------------------------------------
    1040              : 
    1041              : !!****f* m_efmas/efmas_analysis
    1042              : !! NAME
    1043              : !! efmas_analysis
    1044              : !!
    1045              : !! FUNCTION
    1046              : !! This routine analyzes the generalized second-order k-derivatives of eigenenergies,
    1047              : !! and compute the effective mass tensor
    1048              : !! (inverse of hessian of eigenvalues with respect to the wavevector)
    1049              : !! in cartesian coordinates along different directions in k-space, or also the transport equivalent effective mass.
    1050              : !!
    1051              : !! INPUTS
    1052              : !!  dtset = dataset structure containing the input variable of the calculation.
    1053              : !!  efmasdeg(nkpt_rbz) <type(efmasdeg_type)>= information about the band degeneracy at each k point
    1054              : !!  efmasval(mband,nkpt_rbz) <type(efmasdeg_type)>= double tensor datastructure
    1055              : !!    efmasval(:,:)%eig2_diag band curvature double tensor
    1056              : !!  kpt_rbz(3,nkpt_rbz)=reduced coordinates of k points.
    1057              : !!  mpert = maximum number of perturbations.
    1058              : !!  mpi_enreg = information about MPI parallelization.
    1059              : !!  nkpt_rbz = number of k-points for each perturbation.
    1060              : !!  rprimd(3,3)=dimensional primitive translations for real space (bohr)
    1061              : !!
    1062              : !! OUTPUT
    1063              : !!
    1064              : !! SOURCE
    1065              : 
    1066           17 :  subroutine efmas_analysis(dtset,efmasdeg,efmasval,kpt_rbz,mpi_enreg,nkpt_rbz,rprimd)
    1067              : 
    1068              :  !Arguments ------------------------------------
    1069              :  !scalars
    1070              :   integer,            intent(in)    :: nkpt_rbz
    1071              :   type(dataset_type), intent(in)    :: dtset
    1072              :   type(MPI_type),     intent(in) :: mpi_enreg
    1073              :  !arrays
    1074              :   real(dp), intent(in) :: rprimd(3,3)
    1075              :   real(dp), intent(in) :: kpt_rbz(3,nkpt_rbz)
    1076              :   type(efmasdeg_type), intent(in) :: efmasdeg(:)
    1077              :   type(efmasval_type), intent(in) :: efmasval(:,:)
    1078              : 
    1079              :  !Local variables-------------------------------
    1080              :   logical :: degenerate
    1081              :   logical :: debug
    1082              :   logical :: print_fsph
    1083           17 :   logical, allocatable :: saddle_warn(:), start_eigf3d_pos(:)
    1084              :   integer :: info, isppol, ideg,jdeg, ikpt,  master,me,spaceworld
    1085              :   integer :: iband, jband, adir,bdir, deg_dim, degl, lwork
    1086              :   integer :: itheta, iphi, ntheta, nphi
    1087              :   integer :: mdim, cdirs, ndirs, io_unit
    1088              :   integer :: ipiv(3)
    1089              :   character(len=500) :: msg, filename
    1090              :   real(dp) :: cosph,costh,sinph,sinth,f3d_scal,weight
    1091              :   real(dp) :: gprimd(3,3)
    1092           17 :   real(dp), allocatable :: unit_r(:), dr_dth(:), dr_dph(:)
    1093           17 :   real(dp), allocatable :: eigenval(:), rwork(:)
    1094           17 :   real(dp), allocatable :: eigf3d(:)
    1095           17 :   real(dp), allocatable :: m_avg(:), m_avg_frohlich(:),m_cart(:,:)
    1096           17 :   real(dp), allocatable :: deigf3d_dth(:), deigf3d_dph(:)
    1097           17 :   real(dp), allocatable :: unit_speed(:,:), transport_tensor(:,:,:)
    1098           17 :   real(dp), allocatable :: cart_rotation(:,:), transport_tensor_eig(:)
    1099           17 :   real(dp), allocatable :: transport_eqv_m(:,:,:), transport_eqv_eigval(:,:), transport_eqv_eigvec(:,:,:)
    1100           17 :   real(dp), allocatable :: transport_tensor_scale(:)
    1101           17 :   real(dp), allocatable :: gq_points_th(:),gq_points_costh(:),gq_points_sinth(:),gq_weights_th(:)
    1102           17 :   real(dp), allocatable :: gq_points_ph(:),gq_points_cosph(:),gq_points_sinph(:),gq_weights_ph(:)
    1103           17 :   real(dp), allocatable :: dirs(:,:)
    1104           17 :   real(dp),allocatable :: prodr(:,:)
    1105              :   !real(dp), allocatable :: f3dfd(:,:,:)
    1106              :   complex(dp) :: matr2d(2,2)
    1107           17 :   complex(dp), allocatable :: eigenvec(:,:), work(:)
    1108           17 :   complex(dp), allocatable :: eig2_diag_cart(:,:,:,:)
    1109           17 :   complex(dp), allocatable :: f3d(:,:), df3d_dth(:,:), df3d_dph(:,:)
    1110           17 :   complex(dp), allocatable :: unitary_tr(:,:), eff_mass(:,:)
    1111           17 :   complex(dp),allocatable :: prodc(:,:)
    1112              : 
    1113              : ! *********************************************************************
    1114              : 
    1115           17 :   debug = .false. ! Prints additional info to std_out
    1116           17 :   print_fsph = .false. ! Open a file and print the angle dependent curvature f(\theta,\phi)
    1117              :                        ! for each band & kpts treated; 1 file per degenerate ensemble of bands.
    1118              :                        ! Angles are those used in the numerical integration.
    1119              : 
    1120              : ! Init parallelism
    1121           17 :   master =0
    1122           17 :   spaceworld=mpi_enreg%comm_cell
    1123           17 :   me=mpi_enreg%me_kpt
    1124              : 
    1125           17 :   isppol = 1
    1126              : 
    1127           17 :   mdim = dtset%efmas_dim
    1128              : 
    1129              : !HERE ALLOCATE
    1130              : 
    1131           17 :   gprimd = rprimd
    1132           17 :   call dgetrf(mdim,mdim,gprimd,mdim,ipiv,info)
    1133           17 :   ABI_MALLOC(rwork,(3))
    1134           17 :   call dgetri(mdim,gprimd,mdim,ipiv,rwork,3,info)
    1135           17 :   ABI_FREE(rwork)
    1136          425 :   gprimd = two_pi*transpose(gprimd)
    1137              : 
    1138           17 :   cdirs = dtset%efmas_calc_dirs
    1139           17 :   ndirs = mdim
    1140           17 :   if(cdirs/=0) ndirs = dtset%efmas_n_dirs
    1141           51 :   ABI_MALLOC(dirs,(3,ndirs))
    1142           17 :   if(cdirs==0) then
    1143           49 :     dirs = zero
    1144           16 :     do adir=1,ndirs
    1145           16 :       dirs(adir,adir)=1.0_dp
    1146              :     end do
    1147           12 :   elseif(cdirs==1) then
    1148          210 :     dirs(:,:) = dtset%efmas_dirs(:,1:ndirs)
    1149           60 :     do adir=1,ndirs
    1150          360 :       dirs(:,adir) = dirs(:,adir)/sqrt(sum(dirs(:,adir)**2))
    1151              :     end do
    1152            2 :   elseif(cdirs==2) then
    1153           18 :     dirs(:,:) = matmul(gprimd,dtset%efmas_dirs(:,1:ndirs))
    1154            2 :     do adir=1,ndirs
    1155            8 :       dirs(:,adir) = dirs(:,adir)/sqrt(sum(dirs(:,adir)**2))
    1156              :     end do
    1157            1 :   elseif(cdirs==3) then
    1158            3 :     dirs(1,:) = sin(dtset%efmas_dirs(1,1:ndirs)*pi/180)*cos(dtset%efmas_dirs(2,1:ndirs)*pi/180)
    1159            3 :     dirs(2,:) = sin(dtset%efmas_dirs(1,1:ndirs)*pi/180)*sin(dtset%efmas_dirs(2,1:ndirs)*pi/180)
    1160            3 :     dirs(3,:) = cos(dtset%efmas_dirs(1,1:ndirs)*pi/180)
    1161              :   end if
    1162              : 
    1163              :   !!! Initialization of integrals for the degenerate case.
    1164           17 :   ntheta   = dtset%efmas_ntheta
    1165           17 :   nphi     = 2*ntheta
    1166           51 :   ABI_MALLOC(gq_points_th,(ntheta))
    1167           34 :   ABI_MALLOC(gq_points_costh,(ntheta))
    1168           34 :   ABI_MALLOC(gq_points_sinth,(ntheta))
    1169           34 :   ABI_MALLOC(gq_weights_th,(ntheta))
    1170           51 :   ABI_MALLOC(gq_points_ph,(nphi))
    1171           34 :   ABI_MALLOC(gq_points_cosph,(nphi))
    1172           34 :   ABI_MALLOC(gq_points_sinph,(nphi))
    1173           34 :   ABI_MALLOC(gq_weights_ph,(nphi))
    1174           17 :   call cgqf(ntheta,1,zero,zero,zero,pi,gq_points_th,gq_weights_th)
    1175              :   !XG180501 : TODO : There is no need to make a Gauss-Legendre integral for the phi variable,
    1176              :   !since the function to be integrated is periodic...
    1177           17 :   call cgqf(nphi,1,zero,zero,zero,2*pi,gq_points_ph,gq_weights_ph)
    1178         1717 :   do itheta=1,ntheta
    1179         1700 :     gq_points_costh(itheta)=cos(gq_points_th(itheta))
    1180         1717 :     gq_points_sinth(itheta)=sin(gq_points_th(itheta))
    1181              :   enddo
    1182         3417 :   do iphi=1,nphi
    1183         3400 :     gq_points_cosph(iphi)=cos(gq_points_ph(iphi))
    1184         3417 :     gq_points_sinph(iphi)=sin(gq_points_ph(iphi))
    1185              :   enddo
    1186              : 
    1187           68 :   ABI_MALLOC(eff_mass,(mdim,mdim))
    1188              : 
    1189              : !XG20180519 : incoherent, efmasdeg is dimensioned at nkpt_rbz, and not at dtset%nkpt ...
    1190           41 :   do ikpt=1,dtset%nkpt
    1191           83 :     do ideg=efmasdeg(ikpt)%deg_range(1),efmasdeg(ikpt)%deg_range(2)
    1192              : 
    1193           42 :      deg_dim    = efmasdeg(ikpt)%degs_bounds(2,ideg) - efmasdeg(ikpt)%degs_bounds(1,ideg) + 1
    1194           42 :      degenerate = (deg_dim>1) .and. (dtset%efmas_deg/=0)
    1195           42 :      degl       = efmasdeg(ikpt)%degs_bounds(1,ideg)-1
    1196              : 
    1197              :      !!! Allocations
    1198          168 :      ABI_MALLOC(eigenvec,(deg_dim,deg_dim))
    1199          126 :      ABI_MALLOC(eigenval,(deg_dim))
    1200              : 
    1201          168 :      ABI_MALLOC(eig2_diag_cart,(3,3,deg_dim,deg_dim))
    1202              : 
    1203          121 :      do iband=1,deg_dim
    1204           79 :         write(std_out,*)"  Compute band ",iband  ! This line here to avoid weird
    1205          322 :         do jband=1,deg_dim
    1206              : 
    1207         2463 :           eff_mass=zero
    1208              : 
    1209         2613 :           eig2_diag_cart(:,:,iband,jband)=efmasval(ideg,ikpt)%eig2_diag(:,:,iband,jband)
    1210        28140 :           eig2_diag_cart(:,:,iband,jband) = matmul(matmul(rprimd,eig2_diag_cart(:,:,iband,jband)),transpose(rprimd))/two_pi**2
    1211              : 
    1212              : 
    1213          280 :           if(.not. degenerate .and. iband==jband) then
    1214              : 
    1215              :             !Compute effective mass tensor from second derivative matrix. Simple inversion.
    1216          371 :             eff_mass(:,:) = eig2_diag_cart(1:mdim,1:mdim,iband,jband)
    1217           29 :             call zgetrf(mdim,mdim,eff_mass(1:mdim,1:mdim),mdim,ipiv,info)
    1218           29 :             ABI_MALLOC(work,(3))
    1219           29 :             call zgetri(mdim,eff_mass(1:mdim,1:mdim),mdim,ipiv,work,3,info)
    1220           29 :             ABI_FREE(work)
    1221              : 
    1222              :             !DIAGONALIZATION
    1223          145 :             ABI_MALLOC(transport_eqv_eigvec,(mdim,mdim,deg_dim))
    1224          608 :             transport_eqv_eigvec=zero
    1225          116 :             ABI_MALLOC(transport_eqv_eigval,(mdim,deg_dim))
    1226          208 :             transport_eqv_eigval=zero
    1227          371 :             transport_eqv_eigvec(:,:,iband) = real(eff_mass(1:mdim,1:mdim),dp)
    1228           29 :             lwork=-1
    1229           29 :             ABI_MALLOC(rwork,(1))
    1230           29 :             call dsyev('V','U',mdim,transport_eqv_eigvec(:,:,iband),mdim,transport_eqv_eigval(:,iband),rwork,lwork,info)
    1231           29 :             lwork = max(1, 3*mdim-1) ! lwork >= max(1, 3*mdim-1)
    1232           29 :             ABI_FREE(rwork)
    1233              : 
    1234           87 :             ABI_MALLOC(rwork,(lwork))
    1235          258 :             rwork=zero
    1236           29 :             call dsyev('V','U',mdim,transport_eqv_eigvec(:,:,iband),mdim,transport_eqv_eigval(:,iband),rwork,lwork,info)
    1237           29 :             ABI_FREE(rwork)
    1238          713 :             transport_eqv_eigvec(:,:,iband) = transpose(transport_eqv_eigvec(:,:,iband)) !So that lines contain eigenvectors.
    1239              : 
    1240              :             !Frohlich average effective mass
    1241           29 :             ABI_MALLOC(m_avg,(1))
    1242           29 :             ABI_MALLOC(m_avg_frohlich,(1))
    1243           29 :             ABI_MALLOC(saddle_warn,(1))
    1244           87 :             ABI_MALLOC(unit_r,(mdim))
    1245           29 :             ABI_MALLOC(start_eigf3d_pos,(1))
    1246              : 
    1247           58 :             m_avg=zero
    1248           58 :             m_avg_frohlich=zero
    1249           58 :             saddle_warn=.false.
    1250              : 
    1251           29 :             if(mdim==3)then
    1252              :               !One has to perform the integral over the sphere
    1253         2828 :               do itheta=1,ntheta
    1254         2800 :                 costh=gq_points_costh(itheta) ; sinth=gq_points_sinth(itheta)
    1255       562828 :                 do iphi=1,nphi
    1256       560000 :                   cosph=gq_points_cosph(iphi) ; sinph=gq_points_sinph(iphi)
    1257       560000 :                   weight=gq_weights_th(itheta)*gq_weights_ph(iphi)
    1258              : 
    1259       560000 :                   unit_r(1)=sinth*cosph
    1260       560000 :                   unit_r(2)=sinth*sinph
    1261       560000 :                   unit_r(3)=costh
    1262              : 
    1263     17920000 :                   f3d_scal=dot_product(unit_r(:),matmul(real(eig2_diag_cart(:,:,iband,jband),dp),unit_r(:)))
    1264      1120000 :                   m_avg = m_avg + weight*sinth*f3d_scal
    1265      1120000 :                   m_avg_frohlich = m_avg_frohlich + weight*sinth/(abs(f3d_scal)**half)
    1266              : 
    1267       560028 :                   if(itheta==1 .and. iphi==1) start_eigf3d_pos = f3d_scal > 0
    1268       562800 :                   if(start_eigf3d_pos(1) .neqv. (f3d_scal>0)) then
    1269        26755 :                     saddle_warn(1)=.true.
    1270              :                   end if
    1271              :                 enddo
    1272              :               enddo
    1273           56 :               m_avg = quarter/pi*m_avg
    1274           56 :               m_avg = one/m_avg
    1275           56 :               m_avg_frohlich = quarter/pi*m_avg_frohlich
    1276           56 :               m_avg_frohlich = m_avg_frohlich**2
    1277           28 :               m_avg_frohlich(1) = DSIGN(m_avg_frohlich(1),m_avg(1))
    1278              : 
    1279              :             endif ! mdim==3
    1280              : 
    1281              :             !EFMAS_DIRS
    1282          116 :             ABI_MALLOC(m_cart,(ndirs,deg_dim))
    1283          261 :             m_cart=zero
    1284          168 :             do adir=1,ndirs
    1285         4338 :               m_cart(adir,1)=1.0_dp/dot_product(dirs(:,adir),matmul(real(eig2_diag_cart(:,:,iband,jband),dp),dirs(:,adir)))
    1286              :             end do
    1287              : 
    1288              :             !PRINTING RESULTS
    1289              :             call print_tr_efmas(std_out,kpt_rbz(:,ikpt),degl+iband,1,mdim,ndirs,dirs,m_cart,rprimd,real(eff_mass,dp), &
    1290              : &             ntheta,m_avg,m_avg_frohlich,saddle_warn,&
    1291          371 : &             transport_eqv_eigval(:,iband:iband),transport_eqv_eigvec(:,:,iband:iband))
    1292              :             call print_tr_efmas(ab_out, kpt_rbz(:,ikpt),degl+iband,1,mdim,ndirs,dirs,m_cart,rprimd,real(eff_mass,dp), &
    1293              : &             ntheta,m_avg,m_avg_frohlich,saddle_warn,&
    1294          371 : &             transport_eqv_eigval(:,iband:iband),transport_eqv_eigvec(:,:,iband:iband))
    1295           29 :             ABI_FREE(m_cart)
    1296           29 :             ABI_FREE(transport_eqv_eigvec)
    1297           29 :             ABI_FREE(transport_eqv_eigval)
    1298           29 :             ABI_FREE(m_avg)
    1299           29 :             ABI_FREE(m_avg_frohlich)
    1300           29 :             ABI_FREE(unit_r)
    1301           29 :             ABI_FREE(saddle_warn)
    1302           29 :             ABI_FREE(start_eigf3d_pos)
    1303              : 
    1304              :           end if !.not.degenerate
    1305              :         end do !jband
    1306              :       end do !iband
    1307              : 
    1308              :       !!! EQV_MASS
    1309           42 :       if(degenerate .and. mdim==3) then
    1310           96 :         ABI_CALLOC(unit_r,(mdim))
    1311           80 :         ABI_CALLOC(dr_dth,(mdim))
    1312           80 :         ABI_CALLOC(dr_dph,(mdim))
    1313          230 :         ABI_CALLOC(f3d,(deg_dim,deg_dim))
    1314          230 :         ABI_CALLOC(df3d_dth,(deg_dim,deg_dim))
    1315          230 :         ABI_CALLOC(df3d_dph,(deg_dim,deg_dim))
    1316          230 :         ABI_CALLOC(unitary_tr,(deg_dim,deg_dim))
    1317           76 :         ABI_CALLOC(eigf3d,(deg_dim))
    1318           48 :         ABI_MALLOC(saddle_warn,(deg_dim))
    1319           32 :         ABI_MALLOC(start_eigf3d_pos,(deg_dim))
    1320           76 :         ABI_CALLOC(m_avg,(deg_dim))
    1321           76 :         ABI_CALLOC(m_avg_frohlich,(deg_dim))
    1322          304 :         ABI_CALLOC(m_cart,(ndirs,deg_dim))
    1323           76 :         ABI_CALLOC(deigf3d_dth,(deg_dim))
    1324           76 :         ABI_CALLOC(deigf3d_dph,(deg_dim))
    1325          240 :         ABI_CALLOC(unit_speed,(mdim,deg_dim))
    1326          652 :         ABI_CALLOC(transport_tensor,(mdim,mdim,deg_dim))
    1327           80 :         ABI_CALLOC(transport_tensor_eig,(mdim))
    1328          636 :         ABI_CALLOC(transport_eqv_m,(mdim,mdim,deg_dim))
    1329          224 :         ABI_CALLOC(transport_eqv_eigval,(mdim,deg_dim))
    1330          636 :         ABI_CALLOC(transport_eqv_eigvec,(mdim,mdim,deg_dim))
    1331           48 :         ABI_MALLOC(prodc,(deg_dim,deg_dim))
    1332           64 :         ABI_MALLOC(prodr,(mdim,mdim))
    1333              :         !ABI_MALLOC(f3dfd,(2,nphi,deg_dim))
    1334           60 :         saddle_warn=.false.
    1335           60 :         start_eigf3d_pos=.true.
    1336              : 
    1337              :         !Hack to print f(theta,phi) & weights to a file
    1338              :         if(print_fsph) then
    1339              :           write(msg,*) degl+1
    1340              :           filename='f_band_'//TRIM(ADJUSTL(msg))//'-'
    1341              :           write(msg,*) degl+deg_dim
    1342              :           filename=TRIM(filename)//TRIM(ADJUSTL(msg))//'.dat'
    1343              :           io_unit = get_unit()
    1344              :           open(io_unit,file=TRIM(filename),status='replace')
    1345              :           write(io_unit,*) 'ntheta=',ntheta,', nphi=',nphi
    1346              :           write(io_unit,*) 'itheta, iphi, weight, f_n(theta,phi)'
    1347              :         end if
    1348              : 
    1349         1616 :         do itheta=1,ntheta
    1350         1600 :           costh=gq_points_costh(itheta) ; sinth=gq_points_sinth(itheta)
    1351       321616 :           do iphi=1,nphi
    1352       320000 :             cosph=gq_points_cosph(iphi) ; sinph=gq_points_sinph(iphi)
    1353       320000 :             weight=gq_weights_th(itheta)*gq_weights_ph(iphi)
    1354              : 
    1355       320000 :             unit_r(1)=sinth*cosph
    1356       320000 :             unit_r(2)=sinth*sinph
    1357       320000 :             unit_r(3)=costh
    1358              : 
    1359       320000 :             dr_dth(1)=costh*cosph
    1360       320000 :             dr_dth(2)=costh*sinph
    1361       320000 :             dr_dth(3)=-sinth
    1362              : 
    1363       320000 :             dr_dph(1)=-sinph  !sin(theta)*
    1364       320000 :             dr_dph(2)=cosph   !cos(theta)*
    1365       320000 :             dr_dph(3)=zero
    1366              : 
    1367      1200000 :             do iband=1,deg_dim
    1368      3960000 :               do jband=1,deg_dim
    1369     63480000 :                 f3d(iband,jband)=DOT_PRODUCT(unit_r,MATMUL(eig2_diag_cart(:,:,iband,jband),unit_r))
    1370      2760000 :                 df3d_dth(iband,jband)=DOT_PRODUCT(dr_dth,MATMUL(eig2_diag_cart(:,:,iband,jband),unit_r))+&
    1371    126960000 : &                DOT_PRODUCT(unit_r,MATMUL(eig2_diag_cart(:,:,iband,jband),dr_dth))
    1372      2760000 :                 df3d_dph(iband,jband)=DOT_PRODUCT(dr_dph,MATMUL(eig2_diag_cart(:,:,iband,jband),unit_r))+&
    1373    127840000 : &                DOT_PRODUCT(unit_r,MATMUL(eig2_diag_cart(:,:,iband,jband),dr_dph))
    1374              :               end do
    1375              :             end do
    1376              :             !DIAGONALIZATION
    1377      4280000 :             eigenvec = f3d        !IN
    1378       320000 :             lwork=-1
    1379       320000 :             ABI_MALLOC(work,(1))
    1380       960000 :             ABI_MALLOC(rwork,(3*deg_dim-2))
    1381       320000 :             call zheev('V','U',deg_dim,eigenvec,deg_dim,eigenval,work,lwork,rwork,info)
    1382       320000 :             lwork=int(work(1))
    1383       320000 :             ABI_FREE(work)
    1384      1200000 :             eigenval = zero
    1385       960000 :             ABI_MALLOC(work,(lwork))
    1386      3760000 :             work=zero; rwork=zero
    1387       320000 :             call zheev('V','U',deg_dim,eigenvec,deg_dim,eigenval,work,lwork,rwork,info)
    1388       320000 :             ABI_FREE(rwork)
    1389       320000 :             ABI_FREE(work)
    1390      4280000 :             unitary_tr = eigenvec !OUT
    1391      1520000 :             eigf3d = eigenval     !OUT
    1392       320060 :             if(itheta==1 .and. iphi==1) start_eigf3d_pos = eigf3d > 0
    1393      1200000 :             do iband=1,deg_dim
    1394      1200000 :               if(start_eigf3d_pos(iband) .neqv. (eigf3d(iband)>0)) then
    1395          188 :                 saddle_warn(iband)=.true.
    1396              :               end if
    1397              :             end do
    1398              : 
    1399              :             !Hack to print f(theta,phi)
    1400              :             if(print_fsph) write(io_unit,*) gq_points_th(itheta), gq_points_ph(iphi), weight, eigf3d(:)
    1401              : 
    1402              :             !!DEBUG-Mech.
    1403              :             !!A=-4.20449; B=0.378191; C=5.309  !Mech's fit
    1404              :             !A=-4.62503023; B=0.68699088; C=5.20516873 !My fit
    1405              :             !R = sqrt(B**2 + C**2*sin(theta)**2*(cos(theta)**2 + sin(theta)**2*sin(phi)**2*cos(phi)**2))
    1406              :             !eigf3d(1) = A - R
    1407              :             !eigf3d(2) = A + R
    1408              : 
    1409              :             !!angular FD
    1410              :             !f3dfd(2,iphi,:)=eigf3d(:)
    1411              : 
    1412      1520000 :             m_avg = m_avg + weight*sinth*eigf3d
    1413      1520000 :             m_avg_frohlich = m_avg_frohlich + weight*sinth/(abs(eigf3d))**half
    1414              : 
    1415       320000 :             prodc=MATMUL_(f3d,unitary_tr,deg_dim,deg_dim) ; f3d=MATMUL_(unitary_tr,prodc,deg_dim,deg_dim,transa='c')
    1416              :             !f3d = MATMUL(CONJG(TRANSPOSE(unitary_tr)),MATMUL(f3d,unitary_tr))
    1417      1200000 :             do iband=1,deg_dim
    1418      1200000 :               eigf3d(iband) = real(f3d(iband,iband),dp)
    1419              :             end do
    1420       320000 :             prodc=MATMUL_(df3d_dth,unitary_tr,deg_dim,deg_dim) ; df3d_dth=MATMUL_(unitary_tr,prodc,deg_dim,deg_dim,transa='c')
    1421              :             !df3d_dth=MATMUL(CONJG(TRANSPOSE(unitary_tr)),MATMUL(df3d_dth,unitary_tr))
    1422      1200000 :             do iband=1,deg_dim
    1423      1200000 :               deigf3d_dth(iband) = real(df3d_dth(iband,iband),dp)
    1424              :             end do
    1425       320000 :             prodc=MATMUL_(df3d_dph,unitary_tr,deg_dim,deg_dim) ; df3d_dph=MATMUL_(unitary_tr,prodc,deg_dim,deg_dim,transa='c')
    1426              :             !df3d_dph = MATMUL(CONJG(TRANSPOSE(unitary_tr)),MATMUL(df3d_dph,unitary_tr))
    1427      1200000 :             do iband=1,deg_dim
    1428      1200000 :               deigf3d_dph(iband) = real(df3d_dph(iband,iband),dp)
    1429              :             end do
    1430              : 
    1431              :             !!DEBUG-Mech.
    1432              :             !eigf3d(1) = A - R
    1433              :             !eigf3d(2) = A + R
    1434              :             !deigf3d_dth(1) = -1./2./R*C**2*(2.*sin(theta)*cos(theta)*(cos(theta)**2 + sin(theta)**2*sin(phi)**2*cos(phi)**2) + 2.*sin(theta)**3*cos(theta)*(sin(phi)**2*cos(phi)**2 - 1))
    1435              :             !deigf3d_dth(2) =  1./2./R*C**2*(2.*sin(theta)*cos(theta)*(cos(theta)**2 + sin(theta)**2*sin(phi)**2*cos(phi)**2) + 2.*sin(theta)**3*cos(theta)*(sin(phi)**2*cos(phi)**2 - 1))
    1436              :             !deigf3d_dph(1) = -1./2./R*C**2*sin(theta)**3*(2.*sin(phi)*cos(phi)**3 - 2.*sin(phi)**3*cos(phi))
    1437              :             !deigf3d_dph(2) =  1./2./R*C**2*sin(theta)**3*(2.*sin(phi)*cos(phi)**3 - 2.*sin(phi)**3*cos(phi))
    1438              : 
    1439              :             !!angular FD
    1440              :             !if(iphi/=1 .and. itheta/=1) then
    1441              :             !  deigf3d_dph(:) = (f3dfd(2,iphi,:)-f3dfd(2,iphi-1,:))/two_pi*nphi/sin(theta)
    1442              :             !else
    1443              :             !  deigf3d_dph(:) = zero
    1444              :             !end if
    1445              :             !if(itheta/=1) then
    1446              :             !  deigf3d_dth(:) = (f3dfd(2,iphi,:)-f3dfd(1,iphi,:))/pi*ntheta
    1447              :             !else
    1448              :             !  deigf3d_dth(:) = zero
    1449              :             !end if
    1450              : 
    1451      1200000 :             unit_speed(1,:) = 2._dp*sinth*cosph*eigf3d + costh*cosph*deigf3d_dth - sinph*deigf3d_dph      !/sin(theta)
    1452      1200000 :             unit_speed(2,:) = 2._dp*sinth*sinph*eigf3d + costh*sinph*deigf3d_dth + cosph*deigf3d_dph      !/sin(theta)
    1453      1200000 :             unit_speed(3,:) = 2._dp*costh*eigf3d - sinth*deigf3d_dth
    1454              : 
    1455      1201600 :             do jdeg=1,deg_dim
    1456      3840000 :               do bdir=1,mdim
    1457     11440000 :                 do adir=1,mdim
    1458              :                   transport_tensor(adir,bdir,jdeg) = transport_tensor(adir,bdir,jdeg) + &
    1459     10560000 : &                weight*sinth*unit_speed(adir,jdeg)*unit_speed(bdir,jdeg)/(ABS(eigf3d(jdeg))**2.5_dp)
    1460              :                 end do
    1461              :               end do
    1462              :             end do
    1463              :           end do !iphi
    1464              :           !!angular FD
    1465              :           !f3dfd(1,:,:) = f3dfd(2,:,:)
    1466              :         end do !itheta
    1467              : 
    1468              :         !Hack to print f(theta,phi)
    1469              :         if(print_fsph) close(io_unit)
    1470              : 
    1471           60 :         m_avg = quarter/pi*m_avg
    1472           60 :         m_avg = one/m_avg
    1473              : 
    1474           60 :         m_avg_frohlich = quarter/pi*m_avg_frohlich
    1475           60 :         m_avg_frohlich = m_avg_frohlich**2
    1476              : 
    1477          588 :         transport_tensor = 1.0_dp/2.0_dp*transport_tensor
    1478              : 
    1479              :         !Effective masses along directions.
    1480           88 :         do adir=1,ndirs
    1481          268 :           do iband=1,deg_dim
    1482          858 :             do jband=1,deg_dim
    1483        13766 :               f3d(iband,jband) = dot_product(dirs(:,adir),matmul(eig2_diag_cart(:,:,iband,jband),dirs(:,adir)))
    1484              :             end do
    1485              :           end do
    1486              :           !f3d(:,:) = eig2_diag_cart(adir,adir,:,:)
    1487          930 :           eigenvec = f3d        !IN
    1488           72 :           lwork=-1
    1489           72 :           ABI_MALLOC(work,(1))
    1490          216 :           ABI_MALLOC(rwork,(3*deg_dim-2))
    1491           72 :           call zheev('V','U',deg_dim,eigenvec,deg_dim,eigenval,work,lwork,rwork,info)
    1492           72 :           lwork=int(work(1))
    1493           72 :           ABI_FREE(work)
    1494          268 :           eigenval = zero
    1495          216 :           ABI_MALLOC(work,(lwork))
    1496          836 :           work=zero; rwork=zero
    1497           72 :           call zheev('V','U',deg_dim,eigenvec,deg_dim,eigenval,work,lwork,rwork,info)
    1498           72 :           ABI_FREE(rwork)
    1499           72 :           ABI_FREE(work)
    1500          930 :           unitary_tr = eigenvec !OUT
    1501          340 :           eigf3d = eigenval     !OUT
    1502          284 :           m_cart(adir,:)=1._dp/eigf3d(:)
    1503              :         end do
    1504              : 
    1505           60 :         do iband=1,deg_dim
    1506              :           !DIAGONALIZATION
    1507          572 :           transport_eqv_eigvec(:,:,iband) = transport_tensor(:,:,iband)
    1508           44 :           lwork=-1
    1509           44 :           ABI_MALLOC(rwork,(1))
    1510           44 :           call dsyev('V','U',mdim,transport_eqv_eigvec(:,:,iband),mdim,transport_tensor_eig,rwork,lwork,info)
    1511           44 :           lwork=int(rwork(1))
    1512           44 :           ABI_FREE(rwork)
    1513          176 :           transport_tensor_eig = zero
    1514          132 :           ABI_MALLOC(rwork,(lwork))
    1515          440 :           rwork=zero
    1516           44 :           call dsyev('V','U',mdim,transport_eqv_eigvec(:,:,iband),mdim,transport_tensor_eig,rwork,lwork,info)
    1517           44 :           ABI_FREE(rwork)
    1518         1100 :           transport_eqv_eigvec(:,:,iband) = transpose(transport_eqv_eigvec(:,:,iband)) !So that lines contain eigenvectors.
    1519              : 
    1520           44 :           prodr=MATMUL_(transport_tensor(:,:,iband),transport_eqv_eigvec(:,:,iband),mdim,mdim,transb='t')
    1521           44 :           transport_tensor(:,:,iband)=MATMUL_(transport_eqv_eigvec(:,:,iband),prodr,mdim,mdim)
    1522              :           !transport_tensor(:,:,iband) = MATMUL(transport_eqv_eigvec(:,:,iband), &
    1523              :           !                              MATMUL(transport_tensor(:,:,iband),TRANSPOSE(transport_eqv_eigvec(:,:,iband))))
    1524              : 
    1525           44 :           transport_eqv_eigval(1,iband) = transport_tensor_eig(2)*transport_tensor_eig(3)*(3._dp/8._dp/pi)**2
    1526           44 :           transport_eqv_eigval(2,iband) = transport_tensor_eig(3)*transport_tensor_eig(1)*(3._dp/8._dp/pi)**2
    1527           44 :           transport_eqv_eigval(3,iband) = transport_tensor_eig(1)*transport_tensor_eig(2)*(3._dp/8._dp/pi)**2
    1528              :           !The transport tensor loses the sign of the effective mass, this restores it.
    1529          176 :           transport_eqv_eigval(:,iband) = DSIGN(transport_eqv_eigval(:,iband),m_avg(iband))
    1530           44 :           transport_eqv_m(1,1,iband) = transport_eqv_eigval(1,iband)
    1531           44 :           transport_eqv_m(2,2,iband) = transport_eqv_eigval(2,iband)
    1532           44 :           transport_eqv_m(3,3,iband) = transport_eqv_eigval(3,iband)
    1533              : 
    1534           44 :           m_avg_frohlich(iband) = DSIGN(m_avg_frohlich(iband),m_avg(iband))
    1535              : 
    1536           44 :           prodr=MATMUL_(transport_eqv_m(:,:,iband),transport_eqv_eigvec(:,:,iband),mdim,mdim)
    1537           60 :           transport_eqv_m(:,:,iband)=MATMUL_(transport_eqv_eigvec(:,:,iband),prodr,mdim,mdim,transa='t')
    1538              :           !transport_eqv_m(:,:,iband) = MATMUL(TRANSPOSE(transport_eqv_eigvec(:,:,iband)), &
    1539              :           !                             MATMUL(transport_eqv_m(:,:,iband),transport_eqv_eigvec(:,:,iband)))
    1540              : 
    1541              :         end do
    1542              : 
    1543              :         call print_tr_efmas(std_out,kpt_rbz(:,ikpt),degl+1,deg_dim,mdim,ndirs,dirs,m_cart,rprimd,transport_eqv_m, &
    1544           16 : &                        ntheta,m_avg,m_avg_frohlich,saddle_warn,transport_eqv_eigval,transport_eqv_eigvec)
    1545              :         call print_tr_efmas(ab_out, kpt_rbz(:,ikpt),degl+1,deg_dim,mdim,ndirs,dirs,m_cart,rprimd,transport_eqv_m, &
    1546           16 : &                        ntheta,m_avg,m_avg_frohlich,saddle_warn,transport_eqv_eigval,transport_eqv_eigvec)
    1547              : 
    1548           16 :         ABI_FREE(unit_r)
    1549           16 :         ABI_FREE(dr_dth)
    1550           16 :         ABI_FREE(dr_dph)
    1551           16 :         ABI_FREE(f3d)
    1552           16 :         ABI_FREE(df3d_dth)
    1553           16 :         ABI_FREE(df3d_dph)
    1554           16 :         ABI_FREE(unitary_tr)
    1555           16 :         ABI_FREE(eigf3d)
    1556           16 :         ABI_FREE(saddle_warn)
    1557           16 :         ABI_FREE(start_eigf3d_pos)
    1558           16 :         ABI_FREE(m_avg)
    1559           16 :         ABI_FREE(m_avg_frohlich)
    1560           16 :         ABI_FREE(m_cart)
    1561           16 :         ABI_FREE(deigf3d_dth)
    1562           16 :         ABI_FREE(deigf3d_dph)
    1563           16 :         ABI_FREE(unit_speed)
    1564           16 :         ABI_FREE(transport_tensor)
    1565           16 :         ABI_FREE(transport_tensor_eig)
    1566           16 :         ABI_FREE(transport_eqv_m)
    1567           16 :         ABI_FREE(transport_eqv_eigval)
    1568           16 :         ABI_FREE(transport_eqv_eigvec)
    1569           16 :         ABI_FREE(prodc)
    1570           16 :         ABI_FREE(prodr)
    1571              :         !ABI_FREE(f3dfd)
    1572              : 
    1573            2 :       elseif (degenerate .and. mdim==2) then
    1574              : 
    1575            5 :         ABI_CALLOC(unit_r,(mdim))
    1576            4 :         ABI_CALLOC(dr_dph,(mdim))
    1577           15 :         ABI_CALLOC(f3d,(deg_dim,deg_dim))
    1578           15 :         ABI_CALLOC(df3d_dph,(deg_dim,deg_dim))
    1579           15 :         ABI_CALLOC(unitary_tr,(deg_dim,deg_dim))
    1580            5 :         ABI_CALLOC(eigf3d,(deg_dim))
    1581            3 :         ABI_MALLOC(saddle_warn,(deg_dim))
    1582            2 :         ABI_MALLOC(start_eigf3d_pos,(deg_dim))
    1583            5 :         ABI_CALLOC(m_avg,(deg_dim))
    1584            5 :         ABI_CALLOC(m_avg_frohlich,(deg_dim))
    1585           13 :         ABI_CALLOC(m_cart,(ndirs,deg_dim))
    1586            5 :         ABI_CALLOC(deigf3d_dph,(deg_dim))
    1587           13 :         ABI_CALLOC(unit_speed,(mdim,deg_dim))
    1588           26 :         ABI_CALLOC(transport_tensor,(mdim,mdim,deg_dim))
    1589           10 :         ABI_CALLOC(cart_rotation,(mdim,mdim))
    1590            4 :         ABI_CALLOC(transport_tensor_eig,(mdim))
    1591           25 :         ABI_CALLOC(transport_eqv_m,(mdim,mdim,deg_dim))
    1592           12 :         ABI_CALLOC(transport_eqv_eigval,(mdim,deg_dim))
    1593           25 :         ABI_CALLOC(transport_eqv_eigvec,(mdim,mdim,deg_dim))
    1594            5 :         ABI_CALLOC(transport_tensor_scale,(deg_dim))
    1595            3 :         ABI_MALLOC(prodc,(deg_dim,deg_dim))
    1596            3 :         ABI_MALLOC(prodr,(mdim,mdim))
    1597            4 :         saddle_warn=.false.
    1598            4 :         start_eigf3d_pos=.true.
    1599              : 
    1600          201 :         do iphi=1,nphi
    1601          200 :           cosph=gq_points_cosph(iphi) ; sinph=gq_points_sinph(iphi)
    1602          200 :           weight=gq_weights_ph(iphi)
    1603              : 
    1604          200 :           unit_r(1)=cosph
    1605          200 :           unit_r(2)=sinph
    1606              : 
    1607          200 :           dr_dph(1)=-sinph
    1608          200 :           dr_dph(2)=cosph
    1609              : 
    1610          800 :           do iband=1,deg_dim
    1611         2600 :             do jband=1,deg_dim
    1612        12600 :               matr2d = eig2_diag_cart(1:mdim,1:mdim,iband,jband)
    1613        21600 :               f3d(iband,jband)=DOT_PRODUCT(unit_r,MATMUL(matr2d,unit_r))
    1614              :               df3d_dph(iband,jband)=DOT_PRODUCT(dr_dph,MATMUL(matr2d,unit_r))+&
    1615        42000 : &              DOT_PRODUCT(unit_r,MATMUL(matr2d,dr_dph))
    1616              :             end do
    1617              :           end do
    1618              : 
    1619              :           !DIAGONALIZATION
    1620         2800 :           eigenvec = f3d        !IN
    1621          200 :           lwork=-1
    1622          200 :           ABI_MALLOC(work,(1))
    1623          600 :           ABI_MALLOC(rwork,(3*deg_dim-2))
    1624          200 :           call zheev('V','U',deg_dim,eigenvec,deg_dim,eigenval,work,lwork,rwork,info)
    1625          200 :           lwork=int(work(1))
    1626          200 :           ABI_FREE(work)
    1627          800 :           eigenval = zero
    1628          600 :           ABI_MALLOC(work,(lwork))
    1629         2600 :           work=zero; rwork=zero
    1630          200 :           call zheev('V','U',deg_dim,eigenvec,deg_dim,eigenval,work,lwork,rwork,info)
    1631          200 :           ABI_FREE(rwork)
    1632          200 :           ABI_FREE(work)
    1633         2800 :           unitary_tr = eigenvec !OUT
    1634         1000 :           eigf3d = eigenval     !OUT
    1635          204 :           if(iphi==1) start_eigf3d_pos = eigf3d > 0
    1636          800 :           do iband=1,deg_dim
    1637          800 :             if(start_eigf3d_pos(iband) .neqv. (eigf3d(iband)>0)) then
    1638            0 :               saddle_warn(iband)=.true.
    1639              :             end if
    1640              :           end do
    1641              : 
    1642         1000 :           m_avg = m_avg + weight*eigf3d
    1643         1000 :           m_avg_frohlich = m_avg_frohlich + weight/(abs(eigf3d))**half
    1644              : 
    1645          200 :           prodc=MATMUL_(f3d,unitary_tr,deg_dim,deg_dim) ; f3d=MATMUL_(unitary_tr,prodc,deg_dim,deg_dim,transa='c')
    1646              :           !f3d = MATMUL(CONJG(TRANSPOSE(unitary_tr)),MATMUL(f3d,unitary_tr))
    1647          800 :           do iband=1,deg_dim
    1648          800 :             eigf3d(iband) = real(f3d(iband,iband),dp)
    1649              :           end do
    1650          200 :           prodc=MATMUL_(df3d_dph,unitary_tr,deg_dim,deg_dim) ; df3d_dph=MATMUL_(unitary_tr,prodc,deg_dim,deg_dim,transa='c')
    1651              :           !df3d_dph = MATMUL(CONJG(TRANSPOSE(unitary_tr)),MATMUL(df3d_dph,unitary_tr))
    1652          800 :           do iband=1,deg_dim
    1653          800 :             deigf3d_dph(iband) = real(df3d_dph(iband,iband),dp)
    1654              :           end do
    1655              : 
    1656          800 :           unit_speed(1,:) = 2._dp*cosph*eigf3d - sinph*deigf3d_dph
    1657          800 :           unit_speed(2,:) = 2._dp*sinph*eigf3d + cosph*deigf3d_dph
    1658              : 
    1659          801 :           do jdeg=1,deg_dim
    1660         2000 :             do bdir=1,mdim
    1661         4200 :               do adir=1,mdim
    1662              :                 transport_tensor(adir,bdir,jdeg) = transport_tensor(adir,bdir,jdeg) + &
    1663         3600 : &                weight*unit_speed(adir,jdeg)*unit_speed(bdir,jdeg)/(ABS(eigf3d(jdeg))**2)
    1664              :               end do
    1665              :             end do
    1666              :           end do
    1667              : 
    1668              :         end do !iphi
    1669              : 
    1670              :         !!!DEBUG
    1671              : 
    1672            4 :         m_avg = half/pi*m_avg
    1673            4 :         m_avg = one/m_avg
    1674              : 
    1675            4 :         m_avg_frohlich = half/pi*m_avg_frohlich
    1676            4 :         m_avg_frohlich = m_avg_frohlich**2
    1677              : 
    1678           22 :         transport_tensor = 1.0_dp/2.0_dp*transport_tensor
    1679              : 
    1680              :         !Effective masses along directions.
    1681            3 :         do adir=1,ndirs
    1682            8 :           do iband=1,deg_dim
    1683           26 :             do jband=1,deg_dim
    1684          420 :               f3d(iband,jband) = dot_product(dirs(:,adir),matmul(eig2_diag_cart(:,:,iband,jband),dirs(:,adir)))
    1685              :             end do
    1686              :           end do
    1687              :           !f3d(:,:) = eig2_diag_cart(adir,adir,:,:)
    1688           28 :           eigenvec = f3d        !IN
    1689            2 :           lwork=-1
    1690            2 :           ABI_MALLOC(work,(1))
    1691            6 :           ABI_MALLOC(rwork,(3*deg_dim-2))
    1692            2 :           call zheev('V','U',deg_dim,eigenvec,deg_dim,eigenval,work,lwork,rwork,info)
    1693            2 :           lwork=int(work(1))
    1694            2 :           ABI_FREE(work)
    1695            8 :           eigenval = zero
    1696            6 :           ABI_MALLOC(work,(lwork))
    1697           26 :           work=zero; rwork=zero
    1698            2 :           call zheev('V','U',deg_dim,eigenvec,deg_dim,eigenval,work,lwork,rwork,info)
    1699            2 :           ABI_FREE(rwork)
    1700            2 :           ABI_FREE(work)
    1701           28 :           unitary_tr = eigenvec !OUT
    1702           10 :           eigf3d = eigenval     !OUT
    1703            9 :           m_cart(adir,:)=1._dp/eigf3d(:)
    1704              :         end do
    1705              : 
    1706            4 :         do iband=1,deg_dim
    1707              :             !DIAGONALIZATION
    1708           24 :           cart_rotation = transport_tensor(:,:,iband)
    1709            3 :           lwork=-1
    1710            3 :           ABI_MALLOC(rwork,(1))
    1711            3 :           call dsyev('V','U',mdim,cart_rotation,mdim,transport_tensor_eig,rwork,lwork,info)
    1712            3 :           lwork=int(rwork(1))
    1713            3 :           ABI_FREE(rwork)
    1714            9 :           transport_tensor_eig = zero
    1715            9 :           ABI_MALLOC(rwork,(lwork))
    1716           21 :           rwork=zero
    1717            3 :           call dsyev('V','U',mdim,cart_rotation,mdim,transport_tensor_eig,rwork,lwork,info)
    1718            3 :           ABI_FREE(rwork)
    1719           21 :           transport_eqv_eigvec(:,:,iband) = transpose(cart_rotation(:,:)) !So that lines contain eigenvectors, not columns.
    1720              : 
    1721            3 :           prodr=MATMUL_(transport_tensor(:,:,iband),cart_rotation,mdim,mdim)
    1722            3 :           transport_tensor(:,:,iband)=MATMUL_(cart_rotation,prodr,mdim,mdim,transa='t')
    1723              :           !transport_tensor(:,:,iband) = MATMUL(TRANSPOSE(cart_rotation),MATMUL(transport_tensor(:,:,iband),cart_rotation))
    1724              : 
    1725            3 :           transport_eqv_eigval(1,iband) = 0.5*m_avg(iband)*(1.0 + transport_tensor_eig(2)/transport_tensor_eig(1))
    1726            3 :           transport_eqv_eigval(2,iband) = transport_eqv_eigval(1,iband)*transport_tensor_eig(1)/transport_tensor_eig(2)
    1727              :           !The transport tensor loses the sign of the effective mass, this restores it.
    1728            9 :           transport_eqv_eigval(:,iband) = SIGN(transport_eqv_eigval(:,iband),m_avg(iband))
    1729            3 :           transport_eqv_m(1,1,iband) = transport_eqv_eigval(1,iband)
    1730            3 :           transport_eqv_m(2,2,iband) = transport_eqv_eigval(2,iband)
    1731            3 :           transport_tensor_scale(iband) = sqrt(transport_tensor_eig(1)*transport_tensor_eig(2))/two_pi
    1732              : 
    1733            3 :           m_avg_frohlich(iband) = SIGN(m_avg_frohlich(iband),m_avg(iband))
    1734              : 
    1735            3 :           prodr=MATMUL_(transport_eqv_m(:,:,iband),cart_rotation,mdim,mdim,transb='t')
    1736            4 :           transport_eqv_m(:,:,iband)=MATMUL_(cart_rotation,prodr,mdim,mdim)
    1737              :           !transport_eqv_m(:,:,iband) = MATMUL(cart_rotation,MATMUL(transport_eqv_m(:,:,iband),TRANSPOSE(cart_rotation)))
    1738              : 
    1739              :         end do
    1740              : 
    1741              :         call print_tr_efmas(std_out,kpt_rbz(:,ikpt),degl+1,deg_dim,mdim,ndirs,dirs,m_cart,rprimd,transport_eqv_m, &
    1742            1 : &                        ntheta,m_avg,m_avg_frohlich,saddle_warn,transport_eqv_eigval,transport_eqv_eigvec,transport_tensor_scale)
    1743              :         call print_tr_efmas(ab_out, kpt_rbz(:,ikpt),degl+1,deg_dim,mdim,ndirs,dirs,m_cart,rprimd,transport_eqv_m, &
    1744            1 : &                        ntheta,m_avg,m_avg_frohlich,saddle_warn,transport_eqv_eigval,transport_eqv_eigvec,transport_tensor_scale)
    1745              : 
    1746            1 :         ABI_FREE(unit_r)
    1747            1 :         ABI_FREE(dr_dph)
    1748            1 :         ABI_FREE(f3d)
    1749            1 :         ABI_FREE(df3d_dph)
    1750            1 :         ABI_FREE(unitary_tr)
    1751            1 :         ABI_FREE(eigf3d)
    1752            1 :         ABI_FREE(saddle_warn)
    1753            1 :         ABI_FREE(start_eigf3d_pos)
    1754            1 :         ABI_FREE(m_avg)
    1755            1 :         ABI_FREE(m_avg_frohlich)
    1756            1 :         ABI_FREE(m_cart)
    1757            1 :         ABI_FREE(deigf3d_dph)
    1758            1 :         ABI_FREE(unit_speed)
    1759            1 :         ABI_FREE(transport_tensor)
    1760            1 :         ABI_FREE(cart_rotation)
    1761            1 :         ABI_FREE(transport_tensor_eig)
    1762            1 :         ABI_FREE(transport_eqv_m)
    1763            1 :         ABI_FREE(transport_eqv_eigval)
    1764            1 :         ABI_FREE(transport_eqv_eigvec)
    1765            1 :         ABI_FREE(transport_tensor_scale)
    1766            1 :         ABI_FREE(prodc)
    1767            1 :         ABI_FREE(prodr)
    1768              : 
    1769           25 :       elseif (degenerate .and. mdim==1) then
    1770              : 
    1771           15 :         ABI_CALLOC(f3d,(deg_dim,deg_dim))
    1772           15 :         ABI_CALLOC(unitary_tr,(deg_dim,deg_dim))
    1773            5 :         ABI_CALLOC(eigf3d,(deg_dim))
    1774           10 :         ABI_CALLOC(m_cart,(ndirs,deg_dim))
    1775           14 :         ABI_CALLOC(transport_eqv_m,(mdim,mdim,deg_dim))
    1776            5 :         ABI_CALLOC(m_avg,(deg_dim))
    1777            5 :         ABI_CALLOC(m_avg_frohlich,(deg_dim))
    1778            3 :         ABI_MALLOC(saddle_warn,(deg_dim))
    1779              : 
    1780            4 :         saddle_warn=.false.
    1781              : 
    1782           13 :         f3d(:,:) = eig2_diag_cart(1,1,:,:)
    1783              : 
    1784              :         !DIAGONALIZATION
    1785           14 :         eigenvec = f3d        !IN
    1786            1 :         lwork=-1
    1787            1 :         ABI_MALLOC(work,(1))
    1788            3 :         ABI_MALLOC(rwork,(3*deg_dim-2))
    1789            1 :         call zheev('V','U',deg_dim,eigenvec,deg_dim,eigenval,work,lwork,rwork,info)
    1790            1 :         lwork=int(work(1))
    1791            1 :         ABI_FREE(work)
    1792            4 :         eigenval = zero
    1793            3 :         ABI_MALLOC(work,(lwork))
    1794           13 :         work=zero; rwork=zero
    1795            1 :         call zheev('V','U',deg_dim,eigenvec,deg_dim,eigenval,work,lwork,rwork,info)
    1796            1 :         ABI_FREE(rwork)
    1797            1 :         ABI_FREE(work)
    1798           14 :         unitary_tr = eigenvec !OUT
    1799            5 :         eigf3d = eigenval     !OUT
    1800              : 
    1801            4 :         transport_eqv_m(1,1,:)=1._dp/eigf3d(:)
    1802              : 
    1803              :         !Effective masses along directions.
    1804            2 :         do adir=1,ndirs
    1805            4 :           do iband=1,deg_dim
    1806           13 :             do jband=1,deg_dim
    1807          210 :               f3d(iband,jband) = dot_product(dirs(:,adir),matmul(eig2_diag_cart(:,:,iband,jband),dirs(:,adir)))
    1808              :             end do
    1809              :           end do
    1810           14 :           eigenvec = f3d        !IN
    1811            1 :           lwork=-1
    1812            1 :           ABI_MALLOC(work,(1))
    1813            3 :           ABI_MALLOC(rwork,(3*deg_dim-2))
    1814            1 :           call zheev('V','U',deg_dim,eigenvec,deg_dim,eigenval,work,lwork,rwork,info)
    1815            1 :           lwork=int(work(1))
    1816            1 :           ABI_FREE(work)
    1817            4 :           eigenval = zero
    1818            3 :           ABI_MALLOC(work,(lwork))
    1819           13 :           work=zero; rwork=zero
    1820            1 :           call zheev('V','U',deg_dim,eigenvec,deg_dim,eigenval,work,lwork,rwork,info)
    1821            1 :           ABI_FREE(rwork)
    1822            1 :           ABI_FREE(work)
    1823            5 :           eigf3d = eigenval     !OUT
    1824            5 :           m_cart(adir,:)=1._dp/eigf3d(:)
    1825              :         end do
    1826              : 
    1827              :         call print_tr_efmas(std_out,kpt_rbz(:,ikpt),degl+1,deg_dim,mdim,ndirs,dirs,m_cart,rprimd,transport_eqv_m,&
    1828            1 : &          ntheta,m_avg,m_avg_frohlich,saddle_warn)
    1829              :         call print_tr_efmas(ab_out, kpt_rbz(:,ikpt),degl+1,deg_dim,mdim,ndirs,dirs,m_cart,rprimd,transport_eqv_m,&
    1830            1 : &          ntheta,m_avg,m_avg_frohlich,saddle_warn)
    1831              : 
    1832            1 :         ABI_FREE(f3d)
    1833            1 :         ABI_FREE(unitary_tr)
    1834            1 :         ABI_FREE(eigf3d)
    1835            1 :         ABI_FREE(m_cart)
    1836            1 :         ABI_FREE(transport_eqv_m)
    1837            1 :         ABI_FREE(m_avg)
    1838            1 :         ABI_FREE(m_avg_frohlich)
    1839            1 :         ABI_FREE(saddle_warn)
    1840              :       end if !(degenerate)
    1841              : 
    1842           42 :       ABI_FREE(eig2_diag_cart)
    1843           42 :       ABI_FREE(eigenval)
    1844           66 :       ABI_FREE(eigenvec)
    1845              :     end do !ideg
    1846              : 
    1847              :   end do !ikpt
    1848              : 
    1849           17 :   ABI_FREE(eff_mass)
    1850           17 :   ABI_FREE(dirs)
    1851           17 :   ABI_FREE(gq_points_th)
    1852           17 :   ABI_FREE(gq_points_costh)
    1853           17 :   ABI_FREE(gq_points_sinth)
    1854           17 :   ABI_FREE(gq_weights_th)
    1855           17 :   ABI_FREE(gq_points_ph)
    1856           17 :   ABI_FREE(gq_points_cosph)
    1857           17 :   ABI_FREE(gq_points_sinph)
    1858           17 :   ABI_FREE(gq_weights_ph)
    1859              : 
    1860           17 :   write(std_out,'(3a)') ch10,' END OF EFFECTIVE MASSES SECTION',ch10
    1861           17 :   write(ab_out, '(3a)') ch10,' END OF EFFECTIVE MASSES SECTION',ch10
    1862              : 
    1863           17 :  end subroutine efmas_analysis
    1864              : !!***
    1865              : 
    1866              : !----------------------------------------------------------------------
    1867              : 
    1868              : !!****f* m_efmas/MATMUL_DP
    1869              : !! NAME
    1870              : !! MATMUL_DP
    1871              : !!
    1872              : !! FUNCTION
    1873              : !! Mimic MATMUL Fortran intrinsic function with BLAS3: C=A.B
    1874              : !! This is a temporary workaround to make tests pass on intel/mkl architectures
    1875              : !! Real version
    1876              : !!
    1877              : !! INPUTS
    1878              : !!  aa(:,:),bb(:,:)= input matrices
    1879              : !!  mm,nn= sizes of output matrix
    1880              : !!  [transa,transb]= equivalent to transa, transb args of gemm ('n','t','c')
    1881              : !!                   if not present, default is 'n'.
    1882              : !!
    1883              : !! OUTPUT
    1884              : !!  MATMUL_DP(mm,nn)= output matrix A.B
    1885              : !!
    1886              : !! SOURCE
    1887              : 
    1888          188 : function MATMUL_DP(aa,bb,mm,nn,transa,transb)
    1889              : 
    1890              : !Arguments ------------------------------------
    1891              : !scalars
    1892              :  integer,intent(in) :: mm,nn
    1893              :  character(len=1),optional,intent(in) :: transa,transb
    1894              : !arrays
    1895              :  real(dp),intent(in) :: aa(:,:),bb(:,:)
    1896              :  real(dp) :: MATMUL_DP(mm,nn)
    1897              : 
    1898              : !Local variables-------------------------------
    1899              :  integer :: kk,lda,ldb
    1900              :  character(len=1) :: transa_,transb_
    1901              : 
    1902              : ! *************************************************************************
    1903              : 
    1904          188 :  transa_='n';if (present(transa)) transa_=transa
    1905          188 :  transb_='n';if (present(transb)) transb_=transb
    1906              : 
    1907          188 :  lda=size(aa,1) ; ldb=size(bb,1)
    1908              : 
    1909          188 :  if (transa_=='n') then
    1910          141 :    kk=size(aa,2)
    1911          141 :    if (size(aa,1)/=mm) then
    1912            0 :      ABI_BUG('Error in sizes!')
    1913              :    end if
    1914              :  else
    1915           47 :    kk=size(aa,1)
    1916           47 :    if (size(aa,2)/=mm) then
    1917            0 :      ABI_BUG('Error in sizes!')
    1918              :    end if
    1919              :  end if
    1920              : 
    1921          188 :  if (transb_=='n') then
    1922          141 :    if (size(bb,1)/=kk.or.size(bb,2)/=nn) then
    1923            0 :      ABI_BUG('Error in sizes!')
    1924              :    end if
    1925              :  else
    1926           47 :    if (size(bb,1)/=nn.or.size(bb,2)/=kk) then
    1927            0 :      ABI_BUG('Error in sizes!')
    1928              :    end if
    1929              :  end if
    1930              : 
    1931          188 :  call DGEMM(transa_,transb_,mm,nn,kk,one,aa,lda,bb,ldb,zero,MATMUL_DP,mm)
    1932              : 
    1933              : end function MATMUL_DP
    1934              : !!***
    1935              : 
    1936              : !----------------------------------------------------------------------
    1937              : 
    1938              : !!****f* m_efmas/MATMUL_DPC
    1939              : !! NAME
    1940              : !! MATMUL_DPC
    1941              : !!
    1942              : !! FUNCTION
    1943              : !! Mimic MATMUL Fortran intrinsic function with BLAS3
    1944              : !! This is a temporary workaround to make tests pass on intel/mkl architectures
    1945              : !! Complex version
    1946              : !!
    1947              : !! INPUTS
    1948              : !!  aa(:,:),bb(:,:)= input matrices
    1949              : !!  mm,nn= sizes of output matrix
    1950              : !!  [transa,transb]= equivalent to transa, transb args of gemm ('n','t','c')
    1951              : !!                   if not present, default is 'n'.
    1952              : !!
    1953              : !! OUTPUT
    1954              : !!  MATMUL_DPC(:,:)= output matrix A.B
    1955              : !!
    1956              : !! SOURCE
    1957              : 
    1958      1920800 : function MATMUL_DPC(aa,bb,mm,nn,transa,transb)
    1959              : 
    1960              : !Arguments ------------------------------------
    1961              : !scalars
    1962              :  integer,intent(in) :: mm,nn
    1963              :  character(len=1),optional,intent(in) :: transa,transb
    1964              : !arrays
    1965              :  complex(dp),intent(in) :: aa(:,:),bb(:,:)
    1966              :  complex(dp) :: MATMUL_DPC(mm,nn)
    1967              : 
    1968              : !Local variables-------------------------------
    1969              :  integer :: kk,lda,ldb
    1970              :  character(len=1) :: transa_,transb_
    1971              : ! *************************************************************************
    1972              : 
    1973      1920800 :  transa_='n';if (present(transa)) transa_=transa
    1974      1920800 :  transb_='n';if (present(transb)) transb_=transb
    1975              : 
    1976      1920800 :  lda=size(aa,1) ; ldb=size(bb,1)
    1977              : 
    1978      1920800 :  if (transa_=='n') then
    1979       960400 :    kk=size(aa,2)
    1980       960400 :    if (size(aa,1)/=mm) then
    1981            0 :      ABI_BUG('Error in sizes!')
    1982              :    end if
    1983              :  else
    1984       960400 :    kk=size(aa,1)
    1985       960400 :    if (size(aa,2)/=mm) then
    1986            0 :      ABI_BUG('Error in sizes!')
    1987              :    end if
    1988              :  end if
    1989              : 
    1990      1920800 :  if (transb_=='n') then
    1991      1920800 :    if (size(bb,1)/=kk.or.size(bb,2)/=nn) then
    1992            0 :      ABI_BUG('Error in sizes!')
    1993              :    end if
    1994              :  else
    1995            0 :    if (size(bb,1)/=nn.or.size(bb,2)/=kk) then
    1996            0 :      ABI_BUG('Error in sizes!')
    1997              :    end if
    1998              :  end if
    1999              : 
    2000      1920800 :  call ZGEMM(transa_,transb_,mm,nn,kk,cone,aa,lda,bb,ldb,czero,MATMUL_DPC,mm)
    2001              : 
    2002              : end function MATMUL_DPC
    2003              : !!***
    2004              : 
    2005     14366357 : end module m_efmas
    2006              : !!***
        

Generated by: LCOV version 2.3-1