LCOV - code coverage report
Current view: top level - src/78_eph - m_rta.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 89.0 % 1004 894
Test Date: 2026-11-08 02:25:56 Functions: 100.0 % 16 16
Branches: 60.6 % 4379 2652

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_rta
       2                 :             : !! NAME
       3                 :             : !!  m_rta
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!  This module provides objects and procedures to compute transport properties by solving the
       7                 :             : !!  linearized Boltzmann transport equation (BTE) in the relaxation-time approximation (RTA).
       8                 :             : !!  or within the Iterative Bolztmann Equation (IBTE).
       9                 :             : !!  The RTA has two different flavors: Self-energy Relaxation Time Approximation (SERTA)
      10                 :             : !!  in which the back-scattering term is completely ignored and the Momentum-Relaxation Time Approximation (MRTA)
      11                 :             : !!  in which backscattering is partly accounter for by multiplying the e-ph self-energy integrand function
      12                 :             : !!  by the efficiency factor alpha that depends on the incoming/outgoing electron group velocity.
      13                 :             : !!  The implementation assumes e-ph scattering although additional scattering mechanisms (e.g. ionized impurities)
      14                 :             : !!  can be easily included once an appropriate model is added to the ab-initio e-ph scattering rates.
      15                 :             : !!
      16                 :             : !! COPYRIGHT
      17                 :             : !!  Copyright (C) 2008-2026 ABINIT group (HM, MG)
      18                 :             : !!  This file is distributed under the terms of the
      19                 :             : !!  GNU General Public License, see ~abinit/COPYING
      20                 :             : !!  or http://www.gnu.org/copyleft/gpl.txt .
      21                 :             : !!
      22                 :             : !! NOTES
      23                 :             : !!  Dimensional analysis for conductivity (sigma), mobility (mu).
      24                 :             : !!
      25                 :             : !!   [sigma] = Siemens/m  with S = Ampere/Volt = Ohm^-1
      26                 :             : !!   [mu] = S L^2 Q
      27                 :             : !!
      28                 :             : !! SOURCE
      29                 :             : 
      30                 :             : #if defined HAVE_CONFIG_H
      31                 :             : #include "config.h"
      32                 :             : #endif
      33                 :             : 
      34                 :             : #include "abi_common.h"
      35                 :             : 
      36                 :             : module m_rta
      37                 :             : 
      38                 :             :  use defs_basis
      39                 :             :  use m_abicore
      40                 :             :  use m_xmpi
      41                 :             :  use m_errors
      42                 :             :  use m_copy
      43                 :             :  use m_nctk
      44                 :             :  use m_wfk
      45                 :             :  use m_ephtk
      46                 :             :  use m_sigmaph
      47                 :             :  use m_dtset
      48                 :             :  use m_dtfil
      49                 :             :  use m_krank
      50                 :             :  use netcdf
      51                 :             : 
      52                 :             :  use defs_datatypes,   only : pseudopotential_type
      53                 :             :  use m_ebands,         only : ebands_t, gaps_t, edos_t, klinterp_t, klinterp_new
      54                 :             :  use m_io_tools,       only : flush_unit, open_file
      55                 :             :  use m_time,           only : cwtime, cwtime_report
      56                 :             :  use m_crystal,        only : crystal_t
      57                 :             :  use m_numeric_tools,  only : bisect, simpson_int, safe_div, arth
      58                 :             :  use m_fstrings,       only : strcat, sjoin, itoa, ltoa, stoa, ftoa, yesno
      59                 :             :  use m_kpts,           only : kpts_timrev_from_kptopt, kpts_map
      60                 :             :  use m_occ,            only : occ_fd, occ_dfde
      61                 :             :  use m_pawtab,         only : pawtab_type
      62                 :             :  use m_ddk,            only : ddkstore_t
      63                 :             : 
      64                 :             :  implicit none
      65                 :             : 
      66                 :             :  private
      67                 :             : !!****
      68                 :             : 
      69                 :             :  public :: rta_driver      ! Compute transport properties within the RTA (SERTA and MRTA)
      70                 :             :  public :: ibte_driver     ! Compute transport properties within the IBTE.
      71                 :             : !!****
      72                 :             : 
      73                 :             : !----------------------------------------------------------------------
      74                 :             : 
      75                 :             : !!****t* m_rta/rta_t
      76                 :             : !! NAME
      77                 :             : !! rta_t
      78                 :             : !!
      79                 :             : !! FUNCTION
      80                 :             : !! Container for transport quantities in the RTA
      81                 :             : !!
      82                 :             : !! SOURCE
      83                 :             : 
      84                 :             : type,public :: rta_t
      85                 :             : 
      86                 :             :    integer :: nsppol
      87                 :             :    ! Number of independent spin polarizations.
      88                 :             : 
      89                 :             :    integer :: nspinor
      90                 :             :    ! Number of spinor components.
      91                 :             : 
      92                 :             :    integer :: nkcalc
      93                 :             :    ! Number of computed k-points i.e. k-points inside the sigma_erange energy window.
      94                 :             : 
      95                 :             :    integer :: ntemp
      96                 :             :    ! Number of temperatures.
      97                 :             : 
      98                 :             :    integer :: nw
      99                 :             :    ! Number of energies (chemical potentials) at which transport quantities are computed
     100                 :             :    ! Same number of energies used in DOS.
     101                 :             : 
     102                 :             :    integer :: bmin, bmax, bsize
     103                 :             :    ! Only bands between bmin and bmax are considered in the integrals
     104                 :             :    ! as we don't compute linewidths for all states.
     105                 :             :    ! bmin = minval(%bstart_ks); bmax = maxval(%bstop_ks)
     106                 :             :    ! bisze = bmax - bmin + 1
     107                 :             : 
     108                 :             :    integer :: nrta
     109                 :             :    ! Number of relaxation-time approximations used (1 for SERTA, 2 for MRTA)
     110                 :             : 
     111                 :             :    real(dp) :: eph_extrael
     112                 :             :    ! Extra electrons per unit cell used to compute SERTA lifetimes in sigmaph.
     113                 :             : 
     114                 :             :    real(dp) :: eph_fermie
     115                 :             :    ! Fermi level specified in the input file when computing the SIGEPH file.
     116                 :             : 
     117                 :             :    real(dp) :: transport_extrael
     118                 :             :    ! Extra electrons per unit cell specified in the input file when computing the SIGEPH file.
     119                 :             : 
     120                 :             :    real(dp) :: transport_fermie
     121                 :             :    ! Fermi level specified in the input file when computing the SIGEPH file.
     122                 :             : 
     123                 :             :    logical :: assume_gap
     124                 :             :    ! True if we are dealing with a semiconductor.
     125                 :             :    ! This parameter is initialized from the value of sigma_erange provided by the user.
     126                 :             : 
     127                 :             :    integer,allocatable :: bstart_ks(:,:)
     128                 :             :    ! bstart_ks(nkcalc, nsppol)
     129                 :             :    ! Initial KS band index included in self-energy matrix elements for each k-point in kcalc.
     130                 :             :    ! Depends on spin because all degenerate states should be included when symmetries are used.
     131                 :             : 
     132                 :             :    integer,allocatable :: bstop_ks(:,:)
     133                 :             :    ! bstop_ks(nkcalc, nsppol)
     134                 :             : 
     135                 :             :    integer,allocatable :: nbcalc_ks(:,:)
     136                 :             :    ! nbcalc_ks(nkcalc, nsppol)
     137                 :             :    ! Number of bands included in self-energy matrix elements for each k-point in kcalc.
     138                 :             :    ! Depends on spin because all degenerate states should be included when symmetries are used.
     139                 :             : 
     140                 :             :   integer,allocatable :: kcalc2ibz(:,:)
     141                 :             :    !kcalc2ibz(nkcalc, 6))
     142                 :             :    ! Mapping ikcalc --> IBZ as reported by listkk.
     143                 :             : 
     144                 :             :   integer,allocatable :: kcalc2ebands(:,:)
     145                 :             :    ! (6, nkcalc)
     146                 :             :    ! Mapping ikcalc --> ebands IBZ
     147                 :             :    ! Note that this array is not necessarily equal to kcalc2ibz computed in sigmaph
     148                 :             :    ! because we may have used sigma_ngkpt to downsample the initial nkpt mesh.
     149                 :             :    ! This array is computed in get_ebands and is equal to kcalc2ibz if sigma_nkpt == ngkpt
     150                 :             : 
     151                 :             :    real(dp),allocatable :: kTmesh(:)
     152                 :             :    ! (%ntemp)
     153                 :             :    ! List of k * T temperatures at which to compute the transport
     154                 :             : 
     155                 :             :    real(dp),allocatable :: eph_mu_e(:)
     156                 :             :    ! (%ntemp)
     157                 :             :    ! Chemical potential at this carrier concentration and temperature from sigeph (lifetime)
     158                 :             : 
     159                 :             :    real(dp),allocatable :: transport_mu_e(:)
     160                 :             :    ! (%ntemp)
     161                 :             :    ! Chemical potential at this carrier concentration and temperature
     162                 :             : 
     163                 :             :    real(dp),allocatable :: eminmax_spin(:,:)
     164                 :             :    ! (2, %nsppol))
     165                 :             :    ! min/Max energy of the original ebands object
     166                 :             : 
     167                 :             :    real(dp),allocatable :: linewidths(:,:,:,:,:)
     168                 :             :    ! (ntemp, bmin:bmax, nkpt, nsppol, nrta)
     169                 :             :    ! Linewidth in the IBZ computed in the SERTA/MRTA.
     170                 :             :    ! Non-zero only for the kcalc k-points.
     171                 :             : 
     172                 :             :    real(dp),allocatable :: vbks(:,:,:,:)
     173                 :             :    ! (3, bmin:bmax, nkpt, nsppol))
     174                 :             :    ! band velocity in Cartesian coordinates in the IBZ
     175                 :             :    ! Non-zero only for the kcalc k-points.
     176                 :             : 
     177                 :             :    type(gaps_t) :: gaps
     178                 :             :    ! gaps of original ebands object. Only if assume_gap
     179                 :             : 
     180                 :             :    type(ebands_t) :: ebands
     181                 :             :    ! bandstructure object used to compute the transport properties
     182                 :             :    ! Allocate using only the relevant bands for transport
     183                 :             :    ! including valence states to allow to compute different doping
     184                 :             : 
     185                 :             :    type(edos_t) :: edos
     186                 :             :    ! electronic density of states
     187                 :             :    ! edos%mesh is the mesh used for vv_dos, vvtau_dos and tau_dos
     188                 :             :    ! (%nw)
     189                 :             : 
     190                 :             :    real(dp),allocatable :: tau_dos(:,:,:,:)
     191                 :             :    ! tau(e) (isotropic average for tau_nk for SERTA and MRTA.
     192                 :             :    ! (nw, ntemp, nsppol, nrta)
     193                 :             : 
     194                 :             :    real(dp),allocatable :: vv_dos(:,:,:,:)
     195                 :             :    ! (v x v)  DOS
     196                 :             :    ! (nw, 3, 3, nsppol)
     197                 :             : 
     198                 :             :    real(dp),allocatable :: vvtau_dos(:,:,:,:,:,:)
     199                 :             :    ! (v x v * tau) DOS
     200                 :             :    ! (nw, 3, 3, ntemp, nsppol, nrta)
     201                 :             : 
     202                 :             :    real(dp),allocatable :: n_ehst(:,:,:)
     203                 :             :     ! (2, %nsppol, %ntemp)
     204                 :             :     ! Number of electrons (e) and holes (h) per unit cell
     205                 :             :     ! The first dimension is for electrons/holes.
     206                 :             :     ! If nsppol == 2, the second dimension is the number of e/h for spin else the total number of e/h summed over spins.
     207                 :             : 
     208                 :             :    real(dp),allocatable :: l0(:,:,:,:,:,:), l1(:,:,:,:,:,:), l2(:,:,:,:,:,:)
     209                 :             :    ! (3, 3, nw, nsppol, ntemp, nrta)
     210                 :             :    ! Onsager coefficients in Cartesian coordinates
     211                 :             : 
     212                 :             :    real(dp),allocatable :: l11_mu(:,:,:,:,:), l12_mu(:,:,:,:,:), l22_mu(:,:,:,:,:)
     213                 :             :    ! (3, 3, nsppol, ntemp, nrta)
     214                 :             :    ! Onsager coefficients in Cartesian coordinates, calculated at the correct mu (at the exact temperature)
     215                 :             : 
     216                 :             :    real(dp),allocatable :: sigma(:,:,:,:,:,:)
     217                 :             :    real(dp),allocatable :: seebeck(:,:,:,:,:,:)
     218                 :             :    real(dp),allocatable :: kappa(:,:,:,:,:,:)
     219                 :             :    real(dp),allocatable :: pi(:,:,:,:,:,:)
     220                 :             :    real(dp),allocatable :: zte(:,:,:,:,:,:)
     221                 :             :    ! (3, 3, nw, nsppol, ntemp, nrta)
     222                 :             :    ! Transport coefficients in Cartesian coordinates
     223                 :             : 
     224                 :             :    real(dp),allocatable :: mobility(:,:,:,:,:,:,:)
     225                 :             :    ! Mobility
     226                 :             :    ! (3, 3, nw, %ntemp, 2, %nsppol, nrta)
     227                 :             :    ! 5-th index is for e-h
     228                 :             : 
     229                 :             :    real(dp),allocatable :: conductivity(:,:,:,:,:)
     230                 :             :    ! Conductivity at the Fermi level
     231                 :             :    ! (3, 3, %ntemp, %nsppol, nrta)
     232                 :             : 
     233                 :             :    real(dp),allocatable :: resistivity(:,:,:,:)
     234                 :             :    ! (3, 3, %ntemp, nrta)
     235                 :             : 
     236                 :             :    real(dp),allocatable :: n(:,:,:)
     237                 :             :    ! (nw, ntemp, 2) carrier density for e/h (n/cm^3)
     238                 :             : 
     239                 :             :    real(dp),allocatable :: mobility_mu(:,:,:,:,:,:)
     240                 :             :    ! (3, 3, 2, nsppol, ntemp, nrta)
     241                 :             :    ! mobility for electrons and holes (third dimension) at transport_mu_e(ntemp)
     242                 :             :    ! Third dimension is for electron/hole
     243                 :             : 
     244                 :             :    real(dp),allocatable :: conductivity_mu(:,:,:,:,:,:)
     245                 :             :    ! (3, 3, 2, nsppol, ntemp, nrta)
     246                 :             :    ! Conductivity in Siemens * cm-1
     247                 :             :    ! computed by summing over k-points rather that by performing an energy integration).
     248                 :             : 
     249                 :             :    real(dp),allocatable :: resistivity_mu(:,:,:,:)
     250                 :             :    ! (3, 3, ntemp, nrta)
     251                 :             :    ! Resistivity obtained by inverting conductivity after summing of e- and holes and spins
     252                 :             :    ! computed by summing over k-points rather that by performing an energy integration).
     253                 :             : 
     254                 :             : 
     255                 :             : 
     256                 :             :  contains
     257                 :             : 
     258                 :             :    procedure :: compute_rta
     259                 :             :    procedure :: compute_rta_mobility
     260                 :             :    procedure :: print_rta_txt_files
     261                 :             :    procedure :: write_tensor
     262                 :             :    procedure :: free => rta_free
     263                 :             :    procedure :: rta_ncwrite
     264                 :             : 
     265                 :             :  end type rta_t
     266                 :             : !!***
     267                 :             : 
     268                 :             : !----------------------------------------------------------------------
     269                 :             : 
     270                 :             : contains  !=====================================================
     271                 :             : !!***
     272                 :             : 
     273                 :             : !----------------------------------------------------------------------
     274                 :             : 
     275                 :             : !!****f* m_rta/rta_driver
     276                 :             : !! NAME
     277                 :             : !! rta_driver
     278                 :             : !!
     279                 :             : !! FUNCTION
     280                 :             : !! Driver to compute transport properties within the RTA.
     281                 :             : !!
     282                 :             : !! INPUTS
     283                 :             : !! dtfil<datafiles_type>=variables related to files.
     284                 :             : !! ngfftc(18)=Coarse FFT mesh.
     285                 :             : !! dtset<dataset_type>=All input variables for this dataset.
     286                 :             : !! ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
     287                 :             : !! cryst<crystal_t>=Crystalline structure
     288                 :             : !! pawtab(ntypat*usepaw)<pawtab_type>=Paw tabulated starting data.
     289                 :             : !! psps<pseudopotential_type>=Variables related to pseudopotentials.
     290                 :             : !! comm=MPI communicator.
     291                 :             : !!
     292                 :             : !! SOURCE
     293                 :             : 
     294                 :          12 : subroutine rta_driver(dtfil, ngfftc, dtset, ebands, cryst, pawtab, psps, comm)
     295                 :             : 
     296                 :             : !Arguments ------------------------------------
     297                 :             : !scalars
     298                 :             :  integer, intent(in) :: comm
     299                 :             :  type(datafiles_type),intent(in) :: dtfil
     300                 :             :  type(dataset_type),intent(in) :: dtset
     301                 :             :  type(crystal_t),intent(in) :: cryst
     302                 :             :  type(ebands_t),intent(in) :: ebands
     303                 :             :  type(pseudopotential_type),intent(in) :: psps
     304                 :             : !arrays
     305                 :             :  integer,intent(in) :: ngfftc(18)
     306                 :             :  type(pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw)
     307                 :             : 
     308                 :             : !Local variables ------------------------------
     309                 :             :  type(rta_t) :: rta
     310                 :             : !arrays
     311                 :             :  integer :: units(2)
     312                 :             : 
     313                 :             : ! *************************************************************************
     314                 :             : 
     315         [ +  + ]:          36 :  units = [std_out, ab_out]
     316                 :          12 :  call wrtout(units, ch10//' Entering transport RTA computation driver.')
     317                 :          12 :  call wrtout(units, sjoin("- Reading carrier lifetimes from:", dtfil%filsigephin), newlines=1, do_flush=.True.)
     318                 :             : 
     319                 :             :  ! Initialize RTA object
     320                 :          12 :  rta = rta_new(dtset, dtfil, ngfftc, cryst, ebands, pawtab, psps, comm)
     321                 :             : 
     322                 :             :  ! Compute RTA transport quantities
     323                 :          12 :  call rta%compute_rta(cryst, dtset, dtfil, comm)
     324                 :             : 
     325                 :          12 :  call rta%free()
     326                 :             : 
     327   [ -  +  -  +  :          12 : end subroutine rta_driver
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  -  
                      + ]
     328                 :             : !!***
     329                 :             : 
     330                 :             : !----------------------------------------------------------------------
     331                 :             : 
     332                 :             : !!****f* m_rta/rta_new
     333                 :             : !! NAME
     334                 :             : !! rta_new
     335                 :             : !!
     336                 :             : !! FUNCTION
     337                 :             : !! Build object to compute RTA transport quantities.
     338                 :             : !!
     339                 :             : !! INPUTS
     340                 :             : !!  dtset<dataset_type>=All input variables for this dataset.
     341                 :             : !!  dtfil<datafiles_type>=variables related to files.
     342                 :             : !!  cryst<crystal_t>=Crystalline structure
     343                 :             : !!  ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
     344                 :             : !!  comm=MPI communicator.
     345                 :             : !!
     346                 :             : !! SOURCE
     347                 :             : 
     348                 :          13 : type(rta_t) function rta_new(dtset, dtfil, ngfftc, cryst, ebands, pawtab, psps, comm) result (new)
     349                 :             : 
     350                 :             : !Arguments -------------------------------------
     351                 :             :  integer, intent(in) :: comm
     352                 :             :  type(dataset_type),intent(in) :: dtset
     353                 :             :  type(datafiles_type),intent(in) :: dtfil
     354                 :             :  type(crystal_t),intent(in) :: cryst
     355                 :             :  type(ebands_t),intent(in) :: ebands
     356                 :             :  type(pseudopotential_type),intent(in) :: psps
     357                 :             : !arrays
     358                 :             :  integer,intent(in) :: ngfftc(18)
     359                 :             :  type(pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw)
     360                 :             : 
     361                 :             : !Local variables ------------------------------
     362                 :             :  integer,parameter :: sppoldbl1 = 1, master = 0
     363                 :             :  integer :: ierr, spin, nprocs, my_rank, ik_ibz, ib, irta, itemp, ndat, nsppol, idat, mband, ikpt
     364                 :             :  real(dp) :: cpu, wall, gflops
     365                 :             :  character(len=500) :: msg
     366                 :             :  character(len=fnlen) :: wfk_fname_dense
     367                 :          13 :  type(ebands_t) :: tmp_ebands, ebands_dense
     368                 :          13 :  type(klinterp_t) :: klinterp
     369                 :          13 :  type(ddkstore_t) :: ds
     370                 :          13 :  type(sigmaph_t) :: sigmaph
     371                 :          13 :  type(krank_t) :: krank
     372                 :             : !arrays
     373                 :             :  integer :: kptrlatt(3,3), units(2), sigma_ngkpt(3)
     374                 :          13 :  integer,allocatable :: indkk(:,:)
     375                 :             :  real(dp) :: extrael_fermie(2), sigma_erange(2)
     376                 :          13 :  real(dp),allocatable :: values_bksd(:,:,:,:), vals_bsd(:,:,:), tmp_array4(:,:,:,:), tmp_array5(:,:,:,:,:)
     377                 :             : !************************************************************************
     378                 :             : 
     379                 :          13 :  call cwtime(cpu, wall, gflops, "start")
     380         [ +  + ]:          39 :  units = [std_out, ab_out]
     381                 :             : 
     382                 :          13 :  my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm)
     383                 :             : 
     384                 :             :  ! Use sigma_erange to understand if we are dealing with a metal or a semiconductor.
     385   [ +  +  +  +  :          15 :  new%assume_gap = (.not. all(dtset%sigma_erange < zero) .or. dtset%gw_qprange /= 0)
             +  +  -  + ]
     386                 :             : 
     387                 :             :  ! Read data from SIGEPH file.
     388                 :             :  sigmaph = sigmaph_read(dtfil%filsigephin, dtset, xmpi_comm_self, msg, ierr, keep_open=.true., &
     389   [ -  +  -  +  :          13 :                         extrael_fermie=extrael_fermie, sigma_ngkpt=sigma_ngkpt, sigma_erange=sigma_erange)
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  -  -  -  -  
          +  -  -  -  -  
          -  +  -  -  -  
             -  -  -  -  
                      - ]
     390         [ -  + ]:          13 :  ABI_CHECK(ierr == 0, msg)
     391                 :             : 
     392                 :             :  !if (any(sigma_erange /= zero)) then
     393                 :             :  !  ABI_CHECK(all(dtset%sigma_erange /= zero), "sigma_erange is required in input with a value compatible with SIGEPH.nc")
     394                 :             :  !  ! Make sure that the two values are consistent
     395                 :             :  !  ! Cannot switch to metallic case if SigmaPH file was produced assuming gapped-system
     396                 :             :  !  if (.not. (all(dtset%sigma_erange < zero) .eqv. all(sigma_erange < zero))) then
     397                 :             :  !    ABI_ERROR("The values of sigma_erange from input and SIGEPH are not compatible")
     398                 :             :  !  end if
     399                 :             :  !end if
     400                 :             : 
     401                 :             :  ! How many RTA approximations have we computed in sigmaph? (SERTA, MRTA ...?)
     402         [ -  + ]:          13 :  new%nrta = 2; if (sigmaph%mrta == 0) new%nrta = 1
     403                 :             : 
     404                 :             :  ! Copy important arrays from sigmaph file.
     405                 :             :  ! Allocate temperature arrays (use same values as the ones used in the SIGEPH calculation).
     406                 :          13 :  new%ntemp = sigmaph%ntemp
     407         [ -  + ]:          13 :  call alloc_copy(sigmaph%kTmesh, new%kTmesh)
     408                 :             : 
     409                 :          13 :  new%nkcalc = sigmaph%nkcalc
     410         [ -  + ]:          13 :  call alloc_copy(sigmaph%bstart_ks, new%bstart_ks)
     411         [ -  + ]:          13 :  call alloc_copy(sigmaph%bstop_ks, new%bstop_ks)
     412         [ -  + ]:          13 :  call alloc_copy(sigmaph%nbcalc_ks, new%nbcalc_ks)
     413         [ -  + ]:          13 :  call alloc_copy(sigmaph%kcalc2ibz, new%kcalc2ibz)
     414                 :             : 
     415   [ +  +  +  +  :         141 :  new%bmin = minval(sigmaph%bstart_ks); new%bmax = maxval(sigmaph%bstop_ks)
             +  +  +  + ]
     416                 :             :  !new%bmin = 1; new%bmax = ebands%mband ! This for debugging purposes, results should not change
     417                 :          13 :  new%bsize = new%bmax - new%bmin + 1
     418                 :             : 
     419                 :          13 :  new%nsppol = ebands%nsppol; new%nspinor = ebands%nspinor
     420                 :          13 :  nsppol = new%nsppol
     421                 :             : 
     422   [ -  +  +  -  :          39 :  ABI_MALLOC(new%eminmax_spin, (2, nsppol))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     423   [ +  -  +  -  :          65 :  new%eminmax_spin = ebands%get_minmax("eig")
          +  -  -  +  -  
             -  +  +  +  
                      + ]
     424                 :             : 
     425         [ +  + ]:          13 :  if (new%assume_gap) then
     426                 :             :    ! Get gaps
     427   [ -  +  -  +  :          12 :    new%gaps = ebands%get_gaps(ierr)
          -  +  -  +  -  
          +  -  +  -  +  
                   -  + ]
     428         [ -  + ]:          12 :    if (ierr /= 0) then
     429         [ #  # ]:           0 :      do spin=1, nsppol
     430         [ #  # ]:           0 :        ABI_WARNING(trim(new%gaps%errmsg_spin(spin)))
     431                 :           0 :        new%gaps%vb_max(spin) = ebands%fermie - 1 * eV_Ha
     432                 :           0 :        new%gaps%cb_min(spin) = ebands%fermie + 1 * eV_Ha
     433                 :             :      end do
     434                 :             :      !ABI_ERROR("ebands_get_gaps returned non-zero exit status. See above warning messages...")
     435                 :           0 :      ABI_WARNING("ebands_get_gaps returned non-zero exit status. See above warning messages...")
     436                 :             :    end if
     437         [ +  - ]:          12 :    if (my_rank == master) call new%gaps%print(units)
     438                 :             :  end if
     439                 :             : 
     440                 :             :  ! =================================================
     441                 :             :  ! Read lifetimes and new%ebands from SIGEPH.nc file
     442                 :             :  ! =================================================
     443                 :             :  ! After this point we have:
     444                 :             :  !
     445                 :             :  !      vbks(3, bmin:bmax, nkpt, nsppol)
     446                 :             :  !      linewidths(self%ntemp, bmin:bmax, nkpt, nsppol, 2)
     447                 :             :  !
     448   [ +  +  +  +  :          46 :  if (any(dtset%sigma_ngkpt /= 0)) then
                   +  + ]
     449                 :             :    ! If integrals are computed with the sigma_ngkpt k-mesh, we need to downsample ebands.
     450                 :             :    !call wrtout(units, sjoin(" SIGMAPH file used sigma_ngkpt:", ltoa(sigma_ngkpt)))
     451                 :           2 :    call wrtout(units, sjoin(" Computing integrals with downsampled sigma_ngkpt:", ltoa(dtset%sigma_ngkpt)))
     452                 :           2 :    kptrlatt = 0
     453                 :           2 :    kptrlatt(1,1) = dtset%sigma_ngkpt(1); kptrlatt(2,2) = dtset%sigma_ngkpt(2); kptrlatt(3,3) = dtset%sigma_ngkpt(3)
     454                 :             : 
     455   [ -  +  -  +  :           2 :    tmp_ebands = ebands%downsample(cryst, kptrlatt, dtset%sigma_nshiftk, dtset%sigma_shiftk)
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                +  -  + ]
     456                 :             :    new%ebands = sigmaph%get_ebands(cryst, tmp_ebands, [new%bmin, new%bmax], &
     457   [ +  +  -  +  :           6 :                                    new%kcalc2ebands, new%linewidths, new%vbks, xmpi_comm_self)
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                      + ]
     458                 :           2 :    call tmp_ebands%free()
     459                 :             :  else
     460                 :             :    !call wrtout(units, sjoin(" Computing integrals with SIGEPH k-mesh:", ebands_kmesh2str(ebands))
     461                 :             :    new%ebands = sigmaph%get_ebands(cryst, ebands, [new%bmin, new%bmax], &
     462   [ +  +  -  +  :          33 :                                    new%kcalc2ebands, new%linewidths, new%vbks, xmpi_comm_self)
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                      + ]
     463   [ +  +  +  + ]:         143 :    kptrlatt = new%ebands%kptrlatt
     464                 :             :  end if
     465                 :             : 
     466                 :             :  !print *, "linewidth_serta", maxval(abs(new%linewidths(:,:,:,:,1)))
     467                 :             :  !print *, "linewidth_mrta", maxval(abs(new%linewidths(:,:,:,:,2)))
     468                 :             :  !print *, "max velocities", maxval(abs(new%vbks))
     469                 :             : 
     470                 :             :  if ( &
     471   [ -  +  -  -  :          13 :      dtset%useria == 888 .and. &
             -  -  -  - ]
     472                 :             :      (dtset%getwfkfine /= 0 .or. dtset%irdwfkfine /= 0 .or. dtset%getwfkfine_filepath /= ABI_NOFILE)) then
     473                 :             : 
     474                 :             :    ! In principle only getwfkfine_filepath is used here
     475                 :           0 :    wfk_fname_dense = trim(dtfil%fnameabi_wfkfine)
     476         [ #  # ]:           0 :    ABI_CHECK(nctk_try_fort_or_ncfile(wfk_fname_dense, msg) == 0, msg)
     477                 :             : 
     478         [ #  # ]:           0 :    call wrtout(units, " EPH double grid interpolation: will read energies from: "//trim(wfk_fname_dense), newlines=1)
     479                 :           0 :    mband = new%ebands%mband
     480                 :             : 
     481                 :             :    !ebands_dense = wfk_read_ebands(wfk_fname_dense, comm)
     482                 :             : 
     483   [ #  #  #  #  :           0 :    tmp_ebands = wfk_read_ebands(wfk_fname_dense, comm)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     484                 :           0 :    ebands_dense = tmp_ebands%chop(1, mband)
     485                 :           0 :    call tmp_ebands%free()
     486         [ #  # ]:           0 :    if (my_rank == master) then
     487                 :           0 :      write(std_out, *)" Using kptrlatt: ", ebands_dense%kptrlatt
     488                 :           0 :      write(std_out, *)"       shiftk: ", ebands_dense%shiftk
     489                 :             :    end if
     490         [ #  # ]:           0 :    ABI_CHECK_IEQ(mband, ebands_dense%mband, "Inconsistent number of bands for the fine and dense grid:")
     491                 :             : 
     492                 :             :    ! Compute v_{nk} on the dense grid in Cartesian coordinates.
     493                 :             :    ! vdiago(3, bmin:bmax, nkpt, nsppol)
     494                 :             :    ! NB: We select bands in [bmin:bmax] but all k-points in the IBZ are computed!
     495                 :           0 :    ds%only_diago = .True.; ds%bmin = new%bmin; ds%bmax = new%bmax; ds%mode = "cart"
     496                 :           0 :    call ds%compute_ddk(wfk_fname_dense, "", dtset, psps, pawtab, ngfftc, comm)
     497                 :             : 
     498                 :             :    ! Transfer data to new%vbks
     499         [ #  # ]:           0 :    ABI_MOVE_ALLOC(ds%vdiago, new%vbks)
     500                 :           0 :    call ds%free()
     501                 :             :    !print *, "vbks:", new%vbks
     502                 :             : 
     503                 :             :    ! Linear interpolation in k-space of the linewidths from input SIGEPH to the dense IBZ provided by fine WFK file.
     504                 :             :    ! First of all transfer linewidths to values_bksd to prepare call to klinterp_new.
     505                 :           0 :    ndat = new%ntemp * new%nrta
     506   [ #  #  #  #  :           0 :    ABI_MALLOC(values_bksd, (new%bmin:new%bmax, new%ebands%nkpt, nsppol, ndat))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     507                 :             : 
     508         [ #  # ]:           0 :    do irta=1,new%nrta
     509         [ #  # ]:           0 :      do spin=1,nsppol
     510         [ #  # ]:           0 :        do ik_ibz=1,new%ebands%nkpt
     511         [ #  # ]:           0 :          do ib=new%bmin,new%bmax
     512         [ #  # ]:           0 :            do itemp=1,new%ntemp
     513                 :           0 :              idat = itemp + new%ntemp * (irta - 1)
     514                 :           0 :              values_bksd(ib, ik_ibz, spin, idat) = new%linewidths(itemp, ib, ik_ibz, spin, irta) ! - t(e)
     515                 :             :            end do
     516                 :             :          end do
     517                 :             :        end do
     518                 :             :      end do
     519                 :             :    end do
     520                 :             : 
     521                 :             :    ! Build linear interpolator for linewidths (use only bsize bands)
     522                 :             :    klinterp = klinterp_new(cryst, new%ebands%kptrlatt, new%ebands%nshiftk, new%ebands%shiftk, new%ebands%kptopt, &
     523                 :           0 :                            new%ebands%kptns, new%bsize, new%ebands%nkpt, nsppol, ndat, values_bksd, comm)
     524         [ #  # ]:           0 :    ABI_FREE(values_bksd)
     525                 :             : 
     526                 :             :    ! HERE we re-malloc new%ebands and %linewidths on the fine k-mesh.
     527                 :             :    ! The call must be executed here, once klinterp has been built.
     528                 :             :    ! After this point we can use new%ebands to allocate stuff.
     529                 :           0 :    call ebands_dense%move_alloc(new%ebands)
     530                 :             : 
     531                 :             :    ! Unlinke the ebands stored in SIGEPH, the eigens read from WFK_FINE have not been
     532                 :             :    ! shifted with the scissors operator or updated according to extrael_fermie so do it now.
     533                 :           0 :    call ephtk_update_ebands(dtset, new%ebands, "GS energies read from WFK_FINE")
     534                 :             : 
     535                 :             :    ! And now interpolate linewidths on the fine k-mesh
     536                 :             :    ! Note: k-points that close to the edge of the pocket may get zero linewidths
     537                 :             :    ! One may fix the problem by using lw(e).
     538   [ #  #  #  #  :           0 :    ABI_REMALLOC(new%linewidths, (new%ntemp, new%bmin:new%bmax, new%ebands%nkpt, nsppol, new%nrta))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
     539   [ #  #  #  #  :           0 :    ABI_MALLOC(vals_bsd, (new%bmin:new%bmax, nsppol, ndat))
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     540                 :             : 
     541                 :           0 :    ierr = 0
     542         [ #  # ]:           0 :    do ik_ibz=1,new%ebands%nkpt
     543                 :             : 
     544                 :           0 :      call klinterp%eval_bsd(new%ebands%kptns(:, ik_ibz), vals_bsd)
     545                 :             :      !vals_bsd = vals_bsd + lw(e)
     546                 :             : 
     547   [ #  #  #  #  :           0 :      if (any(vals_bsd < zero)) then
          #  #  #  #  #  
                      # ]
     548                 :           0 :        ierr = ierr + 1
     549   [ #  #  #  #  :           0 :        where (vals_bsd < zero) vals_bsd = zero
             #  #  #  # ]
     550                 :             :      end if
     551                 :             : 
     552                 :             :      ! Transfer data.
     553         [ #  # ]:           0 :      do spin=1,nsppol
     554         [ #  # ]:           0 :        do irta=1,new%nrta
     555         [ #  # ]:           0 :          do itemp=1,new%ntemp
     556                 :           0 :            idat = itemp + new%ntemp * (irta - 1)
     557         [ #  # ]:           0 :            do ib=new%bmin,new%bmax
     558                 :           0 :              new%linewidths(itemp, ib, ik_ibz, spin, irta) = vals_bsd(ib, spin, idat)
     559                 :             :            end do
     560                 :             :          end do
     561                 :             :        end do
     562                 :             :      end do
     563                 :             : 
     564                 :             :    end do ! ik_ibz
     565                 :             : 
     566         [ #  # ]:           0 :    if (ierr /= 0) then
     567                 :             :      ! This should never happen for linear interpolation.
     568                 :           0 :      ABI_WARNING(sjoin("Linear interpolation produced:", itoa(ierr), " k-points with negative linewidths"))
     569                 :             :    end if
     570                 :             : 
     571         [ #  # ]:           0 :    ABI_FREE(vals_bsd)
     572                 :           0 :    call klinterp%free()
     573                 :             :  end if
     574                 :             : 
     575                 :             :  ! FIXME: I think transport_ngkpt is buggy, wrong ne(T), weird zeros if MRTA ...
     576                 :             :  ! Do we really need this option? Can't we replace it with sigma_ngkpt and eph_task 7?
     577                 :             : 
     578   [ +  +  +  +  :          49 :  if (any(dtset%transport_ngkpt /= 0)) then
                   +  + ]
     579                 :             :    ! Perform further downsampling (useful for debugging purposes)
     580                 :           1 :    call wrtout(units, " Downsampling the k-mesh before computing transport:")
     581                 :           1 :    call wrtout(units, sjoin(" Using transport_ngkpt: ", ltoa(dtset%transport_ngkpt)))
     582                 :           1 :    kptrlatt = 0
     583                 :           1 :    kptrlatt(1, 1) = dtset%transport_ngkpt(1)
     584                 :           1 :    kptrlatt(2, 2) = dtset%transport_ngkpt(2)
     585                 :           1 :    kptrlatt(3, 3) = dtset%transport_ngkpt(3)
     586   [ -  +  -  +  :           1 :    tmp_ebands = new%ebands%downsample(cryst, kptrlatt, 1, [zero, zero, zero])
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                +  -  + ]
     587                 :             : 
     588                 :             :    ! Map the points of the downsampled bands to dense ebands
     589   [ -  +  +  -  :           3 :    ABI_MALLOC(indkk, (6, tmp_ebands%nkpt))
          +  -  +  -  -  
                +  -  + ]
     590                 :             : 
     591                 :           1 :    call krank%from_kptrlatt(new%ebands%nkpt, new%ebands%kptns, new%ebands%kptrlatt, compute_invrank=.False.)
     592                 :             : 
     593         [ -  + ]:           1 :    if (kpts_map("symrec", ebands%kptopt, cryst, krank, tmp_ebands%nkpt, tmp_ebands%kptns, indkk) /= 0) then
     594                 :             :      write(msg, '(3a)' ) &
     595                 :           0 :        "Error while downsampling ebands in the transport driver",ch10, &
     596                 :           0 :        "The k-point could not be generated from a symmetrical one."
     597                 :           0 :      ABI_ERROR(msg)
     598                 :             :    end if
     599                 :             : 
     600                 :           1 :    call krank%free()
     601                 :             : 
     602                 :             :    ! Downsampling linewidths and velocities.
     603                 :           1 :    ABI_MOVE_ALLOC(new%linewidths, tmp_array5)
     604   [ -  +  +  -  :           7 :    ABI_REMALLOC(new%linewidths, (new%ntemp, new%bmin:new%bmax, tmp_ebands%nkpt, nsppol, new%nrta))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  -  +  +  
          -  +  -  +  -  
             -  +  -  + ]
     605         [ +  + ]:          73 :    do ikpt=1,tmp_ebands%nkpt
     606   [ +  +  +  +  :        1369 :      new%linewidths(:,:,ikpt,:,:) = tmp_array5(:,:,indkk(1, ikpt),:,:)
             +  +  +  + ]
     607                 :             :    end do
     608         [ -  + ]:           1 :    ABI_FREE(tmp_array5)
     609                 :             : 
     610                 :           1 :    ABI_MOVE_ALLOC(new%vbks, tmp_array4)
     611   [ -  +  +  -  :           5 :    ABI_REMALLOC(new%vbks, (3, new%bmin:new%bmax, tmp_ebands%nkpt, nsppol))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                      + ]
     612         [ +  + ]:          73 :    do ikpt=1,tmp_ebands%nkpt
     613   [ +  +  +  +  :         433 :      new%vbks(:,:,ikpt,:) = tmp_array4(:,:,indkk(1, ikpt),:)
                   +  + ]
     614                 :             :    end do
     615         [ -  + ]:           1 :    ABI_FREE(tmp_array4)
     616                 :             : 
     617                 :             :    !print *, "after downsampling linewidths"
     618                 :             :    !print *, "linewidth_serta", maxval(abs(new%linewidths(:,:,:,:,1)))
     619                 :             :    !print *, "linewidth_mrta", maxval(abs(new%linewidths(:,:,:,:,2)))
     620                 :             : 
     621         [ -  + ]:           1 :    ABI_FREE(indkk)
     622                 :           1 :    call tmp_ebands%move_alloc(new%ebands)
     623                 :             :  end if
     624                 :             : 
     625                 :             :  ! Same doping case as in sigmaph file.
     626   [ -  +  +  -  :          39 :  ABI_MALLOC(new%eph_mu_e, (new%ntemp))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     627   [ -  +  +  -  :          26 :  ABI_MALLOC(new%transport_mu_e, (new%ntemp))
          -  +  -  +  -  
                      + ]
     628                 :             : 
     629                 :          13 :  new%eph_extrael = extrael_fermie(1)
     630                 :          13 :  new%eph_fermie = extrael_fermie(2)
     631                 :          13 :  new%transport_fermie = dtset%eph_fermie
     632                 :          13 :  new%transport_extrael = dtset%eph_extrael
     633   [ +  -  -  +  :          88 :  new%eph_mu_e = sigmaph%mu_e
          -  -  -  -  +  
                      + ]
     634   [ +  -  -  +  :          88 :  new%transport_mu_e = sigmaph%mu_e
          -  -  -  -  +  
                      + ]
     635                 :             : 
     636   [ -  +  -  - ]:          13 :  if (new%transport_fermie /= zero) new%transport_mu_e = new%transport_fermie
     637                 :             : 
     638   [ +  -  -  + ]:          13 :  if (new%transport_fermie == zero .and. new%transport_extrael /= new%eph_extrael) then
     639                 :             : 
     640                 :             :    if (new%transport_extrael /= new%eph_extrael) then
     641                 :             :      write(msg,'(2(a,e18.8),3a)') &
     642                 :           0 :        ' extrael from SIGEPH: ',new%transport_extrael, ' and input file: ',new%eph_extrael, "differ", ch10, &
     643                 :           0 :        ' Will recompute the chemical potential'
     644                 :           0 :      call wrtout(std_out, msg)
     645                 :             :    end if
     646                 :             : 
     647                 :             :    ! Compute Fermi level for different T values.
     648                 :           0 :    call ebands%get_muT_with_fd(new%ntemp, new%kTmesh, dtset%spinmagntarget, dtset%prtvol, new%transport_mu_e, comm)
     649                 :             :  end if
     650                 :             : 
     651                 :             :  ! TODO: Implement possible change of sigma_erange, useful for convergence studies
     652                 :             :  !   1) Run sigmaph with relatively large sigma_erange.
     653                 :             :  !   2) Decrease energy window in the transport part to analyze the behaviour of transport tensors.
     654                 :             : 
     655                 :             :  ! sigmaph is not needed anymore. Free it.
     656                 :          13 :  sigmaph%ncid = nctk_noid
     657                 :          13 :  call sigmaph%free()
     658                 :             : 
     659                 :          13 :  call cwtime_report(" rta_new", cpu, wall, gflops)
     660                 :             : 
     661   [ -  +  -  +  :          26 : end function rta_new
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  -  -  
          -  -  +  -  -  
          -  -  -  +  -  
          -  -  -  -  -  
          -  -  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                +  -  + ]
     662                 :             : !!***
     663                 :             : 
     664                 :             : !----------------------------------------------------------------------
     665                 :             : 
     666                 :             : !!****f* m_rta/compute_rta
     667                 :             : !! NAME
     668                 :             : !! compute_rta
     669                 :             : !!
     670                 :             : !! FUNCTION
     671                 :             : !!
     672                 :             : !! INPUTS
     673                 :             : !! cryst<crystal_t>=Crystalline structure
     674                 :             : !! dtset<dataset_type>=All input variables for this dataset.
     675                 :             : !! dtfil<datafiles_type>=variables related to files.
     676                 :             : !! comm=MPI communicator.
     677                 :             : !!
     678                 :             : !! SOURCE
     679                 :             : 
     680                 :          13 : subroutine compute_rta(self, cryst, dtset, dtfil, comm)
     681                 :             : 
     682                 :             : !Arguments ------------------------------------
     683                 :             :  integer,intent(in) :: comm
     684                 :             :  class(rta_t),intent(inout) :: self
     685                 :             :  type(dataset_type),intent(in) :: dtset
     686                 :             :  type(datafiles_type),intent(in) :: dtfil
     687                 :             :  type(crystal_t),intent(in) :: cryst
     688                 :             : 
     689                 :             : !Local variables ------------------------------
     690                 :             :  integer,parameter :: nvecs0 = 0, master = 0
     691                 :             :  integer :: nsppol, nkibz, ib, ik_ibz, iw, spin, ii, jj, itemp, irta, itens_, iscal, cnt
     692                 :             :  integer :: ntens, edos_intmeth, ifermi, iel, nvals, my_rank
     693                 :             :  integer :: ncid
     694                 :             :  !character(len=500) :: msg
     695                 :             :  character(len=fnlen) :: path
     696                 :             :  real(dp) :: emin, emax, edos_broad, edos_step, max_occ, kT, Tkelv, linewidth, fact0, cpu, wall, gflops
     697                 :             : !arrays
     698                 :             :  integer :: units(2)
     699                 :             :  real(dp) :: vr(3), dummy_vecs(1,1,1,1,1), work_33(3,3), S_33(3,3), mat33(3,3)
     700                 :          13 :  real(dp),allocatable :: vv_tens(:,:,:,:,:,:,:), out_valsdos(:,:,:,:), dummy_dosvecs(:,:,:,:,:)
     701                 :          13 :  real(dp),allocatable :: out_tensdos(:,:,:,:,:,:), tau_vals(:,:,:,:,:), l0inv_33nw(:,:,:)
     702                 :             : !************************************************************************
     703                 :             : 
     704                 :          13 :  call cwtime(cpu, wall, gflops, "start")
     705                 :          13 :  my_rank = xmpi_comm_rank(comm)
     706         [ +  + ]:          39 :  units = [std_out, ab_out]
     707                 :             : 
     708                 :             :  ! Basic dimensions
     709                 :          13 :  nsppol = self%ebands%nsppol; nkibz = self%ebands%nkpt
     710                 :             : 
     711                 :             :  ! Allocate v x v tensors with and without the lifetimes. Eq 8 of [[cite:Madsen2018]]
     712                 :             :  ! The total number of tensorial entries is ntens and accounts for nrta
     713                 :             :  ! Remember that we haven't computed all the k-points in the IBZ hence we can have zero linewidths
     714                 :             :  ! or very small values when the states are at the band edge so we use safe_dif to avoid SIGFPE.
     715                 :             :  ! Also, note how we store only the states in the energy window.
     716                 :             : 
     717                 :          13 :  nvals = self%ntemp * self%nrta
     718   [ -  +  +  -  :       56295 :  ABI_CALLOC(tau_vals, (self%ntemp, self%nrta, self%bmin:self%bmax, nkibz, nsppol))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  -  +  +  
          -  +  -  +  -  
          -  +  -  +  +  
          +  +  +  +  +  
             +  +  +  + ]
     719                 :             : 
     720                 :          13 :  ntens = (1 + self%ntemp) * self%nrta
     721   [ +  -  -  +  :      651318 :  ABI_CALLOC(vv_tens, (3, 3, 1 + self%ntemp, self%nrta, self%bmin:self%bmax, nkibz, nsppol))
          +  -  -  +  +  
          -  -  +  +  -  
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
          +  +  +  +  +  
          +  +  +  +  +  
             +  +  +  +  
                      + ]
     722                 :             : 
     723                 :             :  cnt = 0
     724         [ +  + ]:          26 :  do spin=1,nsppol
     725         [ +  + ]:        3582 :    do ik_ibz=1,nkibz
     726                 :             :      !cnt = cnt + 1; if (mod(cnt, nprocs) /= my_rank) cycle ! MPI parallelism.
     727         [ +  + ]:        7230 :      do ib=self%bmin,self%bmax
     728                 :             : 
     729         [ +  + ]:       14644 :        vr(:) = self%vbks(:, ib, ik_ibz, spin)
     730                 :             :        ! Store outer product (v_bks x v_bks) in vv_tens. This part does not depend on T and irta.
     731         [ +  + ]:       14644 :        do ii=1,3
     732         [ +  + ]:       47593 :          do jj=1,3
     733         [ +  + ]:      109830 :            vv_tens(ii, jj, 1, 1:self%nrta, ib, ik_ibz, spin) = vr(ii) * vr(jj)
     734                 :             :          end do
     735                 :             :        end do
     736                 :             : 
     737                 :             :        ! Multiply by the lifetime (SERTA and MRTA)
     738         [ +  + ]:       14539 :        do irta=1,self%nrta
     739         [ +  + ]:       52635 :          do itemp=1,self%ntemp
     740                 :       41652 :            linewidth = self%linewidths(itemp, ib, ik_ibz, spin, irta)
     741                 :             :            call safe_div(vv_tens(:,:, 1, irta, ib, ik_ibz, spin), two * linewidth, zero, &
     742   [ +  +  +  + ]:      541476 :                          vv_tens(:,:, 1 + itemp, irta, ib, ik_ibz, spin))
     743                 :       48974 :            call safe_div(one, two * linewidth, zero, tau_vals(itemp, irta, ib, ik_ibz, spin))
     744                 :             :          end do
     745                 :             :        end do
     746                 :             : 
     747                 :             :      end do
     748                 :             :    end do
     749                 :             :  end do
     750                 :             : 
     751                 :             :  !call xmpi_sum(vv_tens, comm, ierr)
     752                 :             :  !call xmpi_sum(tau_vals, comm, ierr)
     753                 :          13 :  call cwtime_report(" compute_rta_loop1", cpu, wall, gflops)
     754                 :             : 
     755                 :             :  ! Compute DOS and VV_DOS and VV_TAU_DOS
     756                 :             :  ! Define integration method and mesh step.
     757         [ -  + ]:          13 :  edos_intmeth = 2; if (dtset%prtdos /= 0) edos_intmeth = dtset%prtdos
     758                 :          13 :  edos_step = dtset%dosdeltae
     759         [ +  - ]:          13 :  if (edos_step == zero) edos_step = 0.001
     760                 :             :  !if (edos_step == zero) edos_step = ten / Ha_meV
     761                 :          13 :  edos_broad = dtset%tsmear
     762                 :             : 
     763                 :             :  ! Set default energy range for DOS
     764                 :             :  ! If sigma_erange is set, get emin and emax from this variable
     765                 :             :  ! MG: TODO This value should be read from SIGEPH
     766                 :             :  ! Recheck metals
     767         [ +  + ]:          13 :  if (self%assume_gap) then
     768                 :          12 :    emin = huge(one); emax = -huge(one)
     769         [ +  + ]:          24 :    do spin=1,self%ebands%nsppol
     770         [ +  - ]:          12 :      if (dtset%sigma_erange(1) >= zero) emin = min(emin, self%gaps%vb_max(spin) + tol2 * eV_Ha - dtset%sigma_erange(1))
     771         [ +  - ]:          24 :      if (dtset%sigma_erange(2) >= zero) emax = max(emax, self%gaps%cb_min(spin) - tol2 * eV_Ha + dtset%sigma_erange(2))
     772                 :             :    end do
     773         [ -  + ]:          12 :    ABI_CHECK(emin /=  huge(one), "Cannot initialize emin")
     774         [ -  + ]:          12 :    ABI_CHECK(emax /= -huge(one), "Cannot initialize emax")
     775                 :             :  else
     776   [ +  -  -  +  :           3 :    emin = minval(self%eminmax_spin(1, :)); emin = emin - tol1 * abs(emin)
             -  -  +  + ]
     777   [ +  -  -  +  :           3 :    emax = maxval(self%eminmax_spin(2, :)); emax = emax + tol1 * abs(emax)
             -  -  +  + ]
     778                 :             :  end if
     779                 :             : 
     780                 :             :  ! Compute DOS, vv_dos and vvtau_DOS (v x v tau)
     781                 :             :  !
     782                 :             :  !    out_valsdos: (nw, 2, nvals, nsppol) array with DOS for scalar quantities if nvals > 0
     783                 :             :  !    out_tensdos: (nw, 2, 3, 3, ntens,  nsppol) array with DOS weighted by tensorial terms if ntens > 0
     784                 :             :  !
     785                 :             :  !  Vectors and tensors are in Cartesian coordinates.
     786                 :             :  !  Note how we compute the DOS only between [emin, emax] to save time and memory
     787                 :             :  !  this implies that IDOS and edos%ifermi are ill-defined
     788                 :             : 
     789                 :             :  self%edos = self%ebands%get_edos_matrix_elements(cryst, self%bsize, &
     790                 :             :                                              nvals, tau_vals, nvecs0, dummy_vecs, ntens, vv_tens, &
     791                 :             :                                              edos_intmeth, edos_step, edos_broad, &
     792                 :             :                                              out_valsdos, dummy_dosvecs, out_tensdos, comm, &
     793   [ +  +  +  +  :          65 :                                              brange=[self%bmin, self%bmax], erange=[emin, emax])
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
                      + ]
     794                 :             : 
     795         [ +  - ]:          13 :  if (my_rank == master) then
     796         [ +  + ]:          39 :    call self%edos%print([std_out, ab_out], header="Computation of DOS, VV_DOS and VVTAU_DOS")
     797                 :             :  end if
     798                 :             : 
     799                 :          13 :  call cwtime_report(" compute_rta_edos", cpu, wall, gflops)
     800                 :             : 
     801                 :             :  ! Unpack data stored in out_tensdos with shape (nw, 2, 3, 3, ntens, nsppol)
     802                 :          13 :  self%nw = self%edos%nw
     803   [ -  +  +  -  :          78 :  ABI_MALLOC(self%tau_dos, (self%nw, self%ntemp, nsppol, self%nrta))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  +  -  +  
          -  -  +  -  +  
                   -  + ]
     804                 :             :  ! TODO: Exchange dims?
     805   [ -  +  +  -  :          65 :  ABI_MALLOC(self%vv_dos, (self%nw, 3, 3, nsppol))
          +  -  -  +  +  
          -  +  -  +  -  
          -  +  -  +  -  
                      + ]
     806   [ -  +  +  -  :          91 :  ABI_MALLOC(self%vvtau_dos, (self%nw, 3, 3, self%ntemp, nsppol, self%nrta))
          +  -  -  +  +  
          -  -  +  +  -  
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
     807                 :             : 
     808         [ +  + ]:          39 :  do irta=1,self%nrta
     809         [ +  + ]:          65 :    do spin=1,nsppol
     810         [ +  + ]:         202 :      do itemp=1,self%ntemp+1
     811                 :             : 
     812                 :         150 :        itens_ = itemp + (irta - 1) * (self%ntemp + 1)
     813         [ +  + ]:         176 :        if (itemp == 1) then
     814   [ +  +  +  +  :      100238 :          self%vv_dos(:,:,:,spin) = out_tensdos(:, 1, :, :, itens_, spin)
                   +  + ]
     815                 :             :        else
     816   [ +  +  +  +  :      233092 :          self%vvtau_dos(:,:,:, itemp-1, spin, irta) = out_tensdos(:, 1, :, :, itens_, spin)
                   +  + ]
     817                 :             :        end if
     818                 :             : 
     819                 :             :      end do
     820                 :             :    end do
     821                 :             :  end do
     822                 :             : 
     823                 :             :  ! Transfer data for tau(e)
     824         [ +  + ]:          39 :  do irta=1,self%nrta
     825         [ +  + ]:          65 :    do spin=1,nsppol
     826         [ +  + ]:         176 :      do itemp=1,self%ntemp
     827                 :         124 :        iscal = itemp + (irta - 1) * self%ntemp
     828         [ +  + ]:       25870 :        self%tau_dos(:, itemp, spin, irta) = out_valsdos(:, 1, iscal, spin)
     829                 :             :      end do
     830                 :             :    end do
     831                 :             :  end do
     832                 :             : 
     833                 :             :  ! Free memory
     834         [ +  - ]:          13 :  ABI_SFREE(out_tensdos)
     835         [ +  - ]:          13 :  ABI_SFREE(tau_vals)
     836         [ +  - ]:          13 :  ABI_SFREE(out_valsdos)
     837         [ -  + ]:          13 :  ABI_SFREE(dummy_dosvecs)
     838         [ +  - ]:          13 :  ABI_SFREE(vv_tens)
     839                 :             : 
     840                 :             :  ! Compute Onsager coefficients. Eq 9 of [[cite:Madsen2018]]
     841                 :             :  ! See also Eqs 41, page 11 of https://arxiv.org/pdf/1402.6979.pdf
     842                 :             :  !
     843                 :             :  !      L^\alpha(\mu, T) = \int de \sigma(e, T) (e - mu)^\alpha (-df/de)
     844                 :             :  !
     845                 :             :  ! with \sigma(e, T) stored in vvtau_dos
     846                 :             : 
     847   [ -  +  +  -  :          78 :  ABI_MALLOC(self%l0, (3, 3, self%nw, self%nsppol, self%ntemp, self%nrta))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  +  -  +  
          -  -  +  -  +  
                   -  + ]
     848   [ -  +  +  -  :          78 :  ABI_MALLOC(self%l1, (3, 3, self%nw, self%nsppol, self%ntemp, self%nrta))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  +  -  +  
          -  -  +  -  +  
                   -  + ]
     849   [ -  +  +  -  :          78 :  ABI_MALLOC(self%l2, (3, 3, self%nw, self%nsppol, self%ntemp, self%nrta))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  +  -  +  
          -  -  +  -  +  
                   -  + ]
     850                 :             : 
     851                 :          13 :  call onsager(0, self%l0)
     852                 :          13 :  call onsager(1, self%l1)
     853                 :          13 :  call onsager(2, self%l2)
     854                 :             : 
     855                 :          13 :  call cwtime_report(" compute_rta_onsanger", cpu, wall, gflops)
     856                 :             : 
     857                 :             :  ! Compute transport tensors, Eqs 12-15 of [[cite:Madsen2018]] and convert to SI units.
     858   [ -  +  +  -  :      334712 :  ABI_CALLOC(self%sigma,   (3, 3, self%nw, self%nsppol, self%ntemp, self%nrta))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  +  -  +  
          -  -  +  -  +  
          -  +  +  +  +  
          +  +  +  +  +  
             +  +  +  + ]
     859   [ -  +  +  -  :      334712 :  ABI_CALLOC(self%seebeck, (3, 3, self%nw, self%nsppol, self%ntemp, self%nrta))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  +  -  +  
          -  -  +  -  +  
          -  +  +  +  +  
          +  +  +  +  +  
             +  +  +  + ]
     860   [ -  +  +  -  :      334712 :  ABI_CALLOC(self%kappa,   (3, 3, self%nw, self%nsppol, self%ntemp, self%nrta))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  +  -  +  
          -  -  +  -  +  
          -  +  +  +  +  
          +  +  +  +  +  
             +  +  +  + ]
     861   [ -  +  +  -  :      334712 :  ABI_CALLOC(self%pi,      (3, 3, self%nw, self%nsppol, self%ntemp, self%nrta))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  +  -  +  
          -  -  +  -  +  
          -  +  +  +  +  
          +  +  +  +  +  
             +  +  +  + ]
     862   [ -  +  +  -  :      334712 :  ABI_CALLOC(self%zte,     (3, 3, self%nw, self%nsppol, self%ntemp, self%nrta))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  +  -  +  
          -  -  +  -  +  
          -  +  +  +  +  
          +  +  +  +  +  
             +  +  +  + ]
     863                 :             : 
     864                 :             :  ! Sigma = L0
     865                 :             :  !TODO : missing maxocc??
     866                 :          13 :  fact0 = (siemens_SI / Bohr_meter / cryst%ucvol)
     867   [ +  -  +  -  :      334660 :  self%sigma = fact0 * self%l0
          +  -  +  -  +  
          -  +  -  -  +  
          -  -  +  +  +  
          +  +  +  +  +  
             +  +  +  + ]
     868                 :             : 
     869                 :             :  ! Used to stored L0^-1
     870   [ -  +  +  -  :          39 :  ABI_MALLOC(l0inv_33nw, (3, 3, self%nw))
          +  -  +  -  -  
                +  -  + ]
     871                 :             : 
     872         [ +  + ]:          39 :  do irta=1,self%nrta
     873         [ +  + ]:          65 :    do spin=1,nsppol
     874         [ +  + ]:         176 :      do itemp=1,self%ntemp
     875                 :             : 
     876                 :         124 :        TKelv = self%kTmesh(itemp) / kb_HaK; if (TKelv < one) Tkelv = one
     877                 :             : 
     878                 :             :        ! S = -1/T L0^-1 L1 = -1/T sigma L1
     879         [ +  + ]:       25844 :        do iw=1,self%nw
     880                 :       25720 :          call inv33(self%l0(:, :, iw, spin, itemp, irta), work_33)
     881   [ +  +  +  + ]:      334360 :          l0inv_33nw(:,:,iw) = work_33
     882   [ +  -  +  +  :     3729524 :          self%seebeck(:,:,iw,spin,itemp,irta) = - (volt_SI / TKelv) * matmul(work_33, self%l1(:,:,iw,spin,itemp,irta))
          +  +  +  +  +  
          +  +  +  +  -  
          +  -  +  -  +  
          -  -  -  -  -  
             +  +  +  + ]
     883                 :             :        end do
     884                 :             : 
     885                 :             :        ! kappa = 1/T [L2 - L1 L0^-1 L1]
     886                 :             :        ! HM: Check why do we need minus sign here to get consistent results with Boltztrap!
     887                 :             :        ! MG: Likely because of a different definition of kappa.
     888         [ +  + ]:       25844 :        do iw=1,self%nw
     889   [ +  +  +  + ]:      334360 :          work_33 = self%l1(:, :, iw, spin, itemp, irta)
     890   [ +  +  +  +  :     2957800 :          work_33 = self%l2(:, :, iw, spin, itemp, irta) - matmul(work_33, matmul(l0inv_33nw(:, :, iw), work_33))
          +  +  +  +  +  
          +  -  +  +  +  
          +  +  +  +  +  
          +  +  +  +  -  
          +  +  +  +  +  
                      - ]
     891                 :             :          !self%kappa(:,:,iw,spin, itemp,spin,irta) = - (volt_SI**2 * fact0 / TKelv) * work_33
     892   [ +  +  +  + ]:      334484 :          self%kappa(:,:,iw,spin,itemp,irta) = + (volt_SI**2 * fact0 / TKelv) * work_33
     893                 :             :        end do
     894                 :             : 
     895                 :             :        ! Peltier pi = -L1 L0^-1
     896         [ +  + ]:       25844 :        do iw=1,self%nw
     897   [ +  +  +  + ]:      334360 :          work_33 = self%l1(:, :, iw, spin, itemp, irta)
     898   [ +  +  +  +  :     2340644 :          self%pi(:,:,iw,spin,itemp,irta) = - volt_SI * matmul(work_33, l0inv_33nw(:, :, iw))
          +  +  +  +  +  
          +  +  -  +  -  
             +  +  +  + ]
     899                 :             :        end do
     900                 :             : 
     901                 :             :        ! ZT: S^T sigma S k^-1 T (tensor form with k=k_electronic only):
     902         [ +  + ]:       25870 :        do iw=1,self%nw
     903   [ +  +  +  + ]:      334360 :          S_33 = self%seebeck(:,:,iw,spin,itemp,irta)
     904   [ -  +  +  -  :     3780840 :          S_33 = matmul(matmul(transpose(S_33), self%sigma(:,:,iw,spin,itemp,irta)), S_33)
          +  -  +  -  -  
          +  -  +  +  +  
          +  +  +  +  +  
          +  +  +  +  -  
          +  -  -  -  -  
          -  -  -  +  -  
          +  +  +  +  +  
          +  +  -  +  -  
                   +  - ]
     905                 :       25720 :          call inv33(self%kappa(:,:,iw,spin,itemp,irta), work_33)
     906   [ +  +  +  +  :     2340644 :          self%zte(:,:,iw,spin,itemp,irta) = matmul(S_33, work_33) * TKelv
          +  +  +  +  +  
          +  +  -  +  -  
             +  +  +  + ]
     907                 :             :        end do
     908                 :             : 
     909                 :             :      end do
     910                 :             :    end do
     911                 :             :  end do
     912                 :             : 
     913         [ -  + ]:          13 :  ABI_FREE(l0inv_33nw)
     914                 :             : 
     915                 :             :  !Here are computed the transport tensors at exact mu (exact temperature and not based on a grid)
     916                 :             : 
     917                 :             : !  do irta=1,self%nrta
     918                 :             : !   do spin=1,nsppol
     919                 :             : !     do itemp=1,self%ntemp
     920                 :             : !
     921                 :             : !       TKelv = self%kTmesh(itemp) / kb_HaK; if (TKelv < one) Tkelv = one
     922                 :             : !
     923                 :             : !       ! S = -1/T L11^-1 L12 = -1/T sigma^-1 L12
     924                 :             : !         call inv33(self%l11_mu(:, :, spin, itemp, irta), work_33)
     925                 :             : !        ! l0inv_33nw(:,:) = work_33
     926                 :             : !         self%seebeck_mu(:,:,spin,itemp,irta) = - (volt_SI / TKelv) * matmul(work_33, self%l12_mu(:,:,spin,itemp,irta))
     927                 :             : !
     928                 :             : !
     929                 :             : !       ! kappa = 1/T [L22 - L21 L11^-1 L12] (in RTA L12=L21)
     930                 :             : !         call inv33(self%l11_mu(:, :, spin, itemp, irta), work_33)
     931                 :             : !         work_33 = matmul(work_33,self%l12_mu(:, :, spin, itemp, irta))
     932                 :             : !         work_33 = self%l22_mu(:, :, spin, itemp, irta) - matmul(self%l12_mu(:, :, spin, itemp, irta), work_33)
     933                 :             : !         self%kappa_mu(:,:,spin,itemp,irta) = + (volt_SI**2 * fact0 / TKelv) * work_33
     934                 :             : !
     935                 :             : !
     936                 :             : !         ! Peltier pi = -L12 L11^-1 (in RTA and only in RTA, if TR sym. is not broken)
     937                 :             : !
     938                 :             : !         call inv33(self%l11_mu(:, :, spin, itemp, irta), work_33)
     939                 :             : !         self%pi_mu(:,:,spin,itemp,irta) = - volt_SI * matmul(self%l12_mu(:, :, spin, itemp, irta), work_33)
     940                 :             : !
     941                 :             : !     end do ! itemp
     942                 :             : !   end do !spin
     943                 :             : ! end do  !irta
     944                 :             : 
     945                 :             : 
     946                 :             : 
     947                 :             :  ! Compute the index of the Fermi level and handle possible out of range condition.
     948                 :          13 :  ifermi = bisect(self%edos%mesh, self%ebands%fermie)
     949   [ +  -  -  + ]:          13 :  if (ifermi == 0 .or. ifermi == self%nw) then
     950                 :           0 :    ABI_ERROR("Bisection could not find the index of the Fermi level in edos%mesh!")
     951                 :             :  end if
     952                 :             : 
     953                 :          13 :  max_occ = two / (self%nspinor * self%nsppol)
     954                 :             : 
     955                 :             :  ! Conductivity
     956   [ -  +  +  -  :          65 :  ABI_MALLOC(self%conductivity, (3, 3, self%ntemp, self%nsppol, self%nrta))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
     957         [ +  + ]:          26 :  do spin=1,self%nsppol
     958         [ +  + ]:          88 :    do itemp=1,self%ntemp
     959         [ +  + ]:         199 :      do irta=1,self%nrta
     960         [ +  + ]:         558 :        do jj=1,3
     961         [ +  + ]:        1612 :          do ii=1,3
     962                 :        1488 :            self%conductivity(ii,jj,itemp,spin,irta) = self%sigma(ii, jj, ifermi, spin, itemp, irta) * 0.01 !m^-1 to cm^-1
     963                 :             :          end do
     964                 :             :        end do
     965                 :             :      end do
     966                 :             :    end do ! itemp
     967                 :             :  end do ! spin
     968                 :             : 
     969   [ -  +  +  -  :          52 :  ABI_MALLOC(self%resistivity, (3, 3, self%ntemp, self%nrta))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
     970         [ +  + ]:          39 :  do irta=1,self%nrta
     971         [ +  + ]:         163 :   do itemp=1,self%ntemp
     972   [ +  +  +  +  :        2728 :     work_33 = sum(self%conductivity(:,:,itemp,:,irta), dim=3)
                   +  + ]
     973   [ +  +  +  + ]:        1612 :     call inv33(work_33, mat33); mat33 = 1e+6_dp * mat33
     974   [ +  +  +  + ]:        1638 :     self%resistivity(:, :, itemp, irta) = mat33
     975                 :             :   end do
     976                 :             :  end do
     977                 :             : 
     978                 :             : 
     979                 :             : 
     980                 :             :  ! Mobility
     981   [ -  +  +  -  :          65 :  ABI_MALLOC(self%n, (self%nw, self%ntemp, 2))
          -  +  +  -  +  
          -  +  -  +  -  
          -  +  -  +  -  
                      + ]
     982   [ -  +  +  -  :          91 :  ABI_MALLOC(self%mobility, (3, 3, self%nw, self%ntemp, 2, self%nsppol, self%nrta))
          -  +  +  -  +  
          -  -  +  +  -  
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
     983                 :             : 
     984         [ +  + ]:          26 :  do spin=1,self%nsppol
     985         [ +  + ]:          88 :    do itemp=1,self%ntemp
     986                 :             :      ! Compute carrier density
     987                 :          62 :      kT = self%kTmesh(itemp)
     988                 :             : 
     989                 :             :      ! MG TODO: I think that here we should use mu_e instead of ifermi.
     990                 :             :      ! Compute carrier density of electrons (ifermi:self%nw)
     991         [ +  + ]:       12922 :      do iw=1,self%nw ! doping
     992                 :             :        self%n(iw,itemp,1) = carriers(self%edos%mesh, self%edos%dos(:,spin) * max_occ, ifermi, self%nw, &
     993   [ +  -  +  + ]:    34127822 :                                      kT, self%edos%mesh(iw)) / cryst%ucvol / Bohr_meter**3
     994                 :             :      end do
     995                 :             : 
     996                 :             :      ! Compute carrier density of holes (1:ifermi)
     997         [ +  + ]:       12922 :      do iw=1,self%nw ! doping
     998                 :             :        self%n(iw,itemp,2) = carriers(self%edos%mesh, self%edos%dos(:,spin) * max_occ, 1, ifermi, &
     999   [ +  -  +  + ]:    34127822 :                                      kT, self%edos%mesh(iw)) / cryst%ucvol / Bohr_meter**3
    1000                 :             :      end do
    1001                 :             : 
    1002         [ +  + ]:       12922 :      self%n(:,itemp,2) = self%n(self%nw,itemp,2) - self%n(:,itemp,2)
    1003                 :             : 
    1004                 :             :      ! Compute mobility
    1005         [ +  + ]:         199 :      do irta=1,self%nrta
    1006         [ +  + ]:         434 :        do iel=1,2
    1007         [ +  + ]:       51812 :          do iw=1,self%nw
    1008         [ +  + ]:      206008 :            do jj=1,3
    1009         [ +  + ]:      668720 :              do ii=1,3
    1010                 :             :                call safe_div(self%sigma(ii, jj, iw, spin, itemp, irta) * 100**2, &
    1011                 :             :                              e_Cb * self%n(iw, itemp, iel), &
    1012                 :      617280 :                              zero, self%mobility(ii, jj, iw, itemp, iel, spin, irta))
    1013                 :             :              end do
    1014                 :             :            end do
    1015                 :             :          end do
    1016                 :             :        end do
    1017                 :             :      end do
    1018                 :             :    end do ! itemp
    1019                 :             :  end do ! spin
    1020                 :             : 
    1021                 :             :  ! Compute RTA mobility
    1022                 :          13 :  call self%compute_rta_mobility(cryst, comm)
    1023                 :             : 
    1024         [ +  - ]:          13 :  if (my_rank == master) then
    1025                 :             :    ! Print RTA results to stdout and other external txt files (for the test suite)
    1026                 :          13 :    call self%print_rta_txt_files(cryst, dtset, dtfil)
    1027                 :             : 
    1028                 :             :    ! Creates the netcdf file used to store the results of the calculation.
    1029         [ +  - ]:          13 :    path = strcat(dtfil%filnam_ds(4), "_RTA.nc")
    1030                 :          13 :    call wrtout(units, ch10//sjoin("- Writing RTA transport results to:", path))
    1031         [ -  + ]:          13 :    NCF_CHECK(nctk_open_create(ncid, path , xmpi_comm_self))
    1032                 :          13 :    call self%rta_ncwrite(cryst, dtset, ncid)
    1033         [ -  + ]:          13 :    NCF_CHECK(nf90_close(ncid))
    1034                 :             :  end if
    1035                 :             : 
    1036   [ -  +  -  +  :          65 :  call cwtime_report(" compute_rta", cpu, wall, gflops)
                   -  + ]
    1037                 :             : 
    1038                 :             : contains
    1039                 :             : 
    1040                 :       25720 :  real(dp) function carriers(wmesh, dos, istart, istop, kT, mu)
    1041                 :             : 
    1042                 :             :  !Arguments -------------------------------------------
    1043                 :             :  real(dp),intent(in) :: kT, mu
    1044                 :             :  real(dp),intent(in) :: wmesh(self%nw), dos(self%nw)
    1045                 :             :  integer,intent(in) :: istart, istop
    1046                 :             : 
    1047                 :             :  !Local variables -------------------------------------
    1048                 :             :  integer :: iw
    1049                 :       25720 :  real(dp) :: kernel(self%nw), integral(self%nw)
    1050                 :             : 
    1051         [ +  + ]:    68255520 :  kernel = zero
    1052         [ +  + ]:    34153480 :  do iw=istart,istop
    1053                 :    34153480 :    kernel(iw) = dos(iw) * occ_fd(wmesh(iw), kT, mu)
    1054                 :             :  end do
    1055                 :       25720 :  call simpson_int(self%nw, edos_step, kernel, integral)
    1056                 :       25720 :  carriers = integral(self%nw)
    1057                 :             : 
    1058                 :       25720 :  end function carriers
    1059                 :             : 
    1060                 :             :  ! Compute L^\alpha(\mu, T) = \int de \sigma(e, T) (e - mu)^\alpha (-df/de)
    1061                 :          39 :  subroutine onsager(order, lorder)
    1062                 :             : 
    1063                 :             :  !Arguments -------------------------------------------
    1064                 :             :  integer,intent(in) :: order
    1065                 :             :  real(dp),intent(out) :: lorder(3, 3, self%nw, self%nsppol, self%ntemp, self%nrta)
    1066                 :             : 
    1067                 :             :  !Local variables -------------------------------------
    1068                 :             :  integer :: spin, iw, imu, irta
    1069                 :             :  real(dp) :: mu, ee, kT
    1070                 :          78 :  real(dp) :: kernel(self%nw,3,3,self%nsppol), integral(self%nw)
    1071                 :             : 
    1072                 :             :  ! Get spin degeneracy
    1073                 :          39 :  max_occ = two / (self%nspinor * self%nsppol)
    1074                 :             : 
    1075         [ +  + ]:         117 :  do irta=1,self%nrta
    1076         [ +  + ]:         489 :    do itemp=1,self%ntemp
    1077                 :         372 :      kT = self%kTmesh(itemp)
    1078                 :             :      ! Loop over chemical potentials mu
    1079         [ +  + ]:       77610 :      do imu=1,self%nw
    1080                 :       77160 :        mu = self%edos%mesh(imu)
    1081                 :             : 
    1082                 :             :        ! Build integrand for given mu
    1083         [ +  + ]:   204766560 :        do iw=1,self%nw
    1084                 :   204689400 :          ee = self%edos%mesh(iw)
    1085         [ +  + ]:   204766560 :          if (order > 0) then
    1086   [ +  +  +  +  :  1910434400 :            kernel(iw,:,:,:) = - max_occ * self%vvtau_dos(iw,:,:,itemp,:,irta) * (ee - mu)** order * occ_dfde(ee, kT, mu)
                   +  + ]
    1087                 :             :          else
    1088   [ +  +  +  +  :   955217200 :            kernel(iw,:,:,:) = - max_occ * self%vvtau_dos(iw,:,:,itemp,:,irta) * occ_dfde(ee, kT, mu)
                   +  + ]
    1089                 :             :          end if
    1090                 :             :        end do
    1091                 :             : 
    1092                 :             :        ! Integrate with simpson_int
    1093         [ +  + ]:      154692 :        do spin=1,self%nsppol
    1094         [ +  + ]:      385800 :          do jj=1,3
    1095         [ +  + ]:     1003080 :            do ii=1,3
    1096                 :      694440 :              call simpson_int(self%nw, edos_step, kernel(:,ii,jj, spin), integral)
    1097                 :      925920 :              lorder(ii, jj, imu, spin, itemp, irta) = integral(self%nw)
    1098                 :             :            end do
    1099                 :             :          end do
    1100                 :             :        end do
    1101                 :             : 
    1102                 :             :      end do ! imu
    1103                 :             :    end do ! itemp
    1104                 :             :  end do ! irta
    1105                 :             : 
    1106                 :          39 :  end subroutine onsager
    1107                 :             : 
    1108                 :             : end subroutine compute_rta
    1109                 :             : !!***
    1110                 :             : 
    1111                 :             : !----------------------------------------------------------------------
    1112                 :             : 
    1113                 :             : !!****f* m_rta/compute_rta_mobility
    1114                 :             : !! NAME
    1115                 :             : !! compute_rta_mobility
    1116                 :             : !!
    1117                 :             : !! FUNCTION
    1118                 :             : !!
    1119                 :             : !! INPUTS
    1120                 :             : !! cryst<crystal_t>=Crystalline structure
    1121                 :             : !! comm=MPI communicator.
    1122                 :             : !!
    1123                 :             : !! SOURCE
    1124                 :             : 
    1125                 :          13 : subroutine compute_rta_mobility(self, cryst, comm)
    1126                 :             : 
    1127                 :             : !Arguments ------------------------------------
    1128                 :             :  class(rta_t),intent(inout) :: self
    1129                 :             :  type(crystal_t),intent(in) :: cryst
    1130                 :             :  integer,intent(in) :: comm
    1131                 :             : 
    1132                 :             : !Local variables ------------------------------
    1133                 :             :  integer :: nsppol, nkibz, ib, ik_ibz, spin, ii, jj, itemp, ieh, cnt, nprocs, irta, time_opt
    1134                 :             :  real(dp) :: eig_nk, mu_e, linewidth, fact, fact0, max_occ, kT, wtk, cpu, wall, gflops
    1135                 :             :  real(dp) :: vr(3), vv_tens(3,3), vv_tenslw(3,3), work_33(3,3), mat33(3,3) !, tmp_tens(3,3)
    1136                 :             : !************************************************************************
    1137                 :             : 
    1138                 :          13 :  call cwtime(cpu, wall, gflops, "start")
    1139                 :             : 
    1140                 :          13 :  nprocs = xmpi_comm_size(comm)
    1141                 :          13 :  nkibz = self%ebands%nkpt; nsppol = self%ebands%nsppol
    1142                 :             : 
    1143                 :          13 :  time_opt = 0 ! This to preserve the previous behaviour in which TR was not used.
    1144                 :             :  !time_opt = -1 ! This to preserve the previous behaviour in which TR was not used.
    1145                 :             : 
    1146   [ -  +  +  -  :        3563 :  ABI_CALLOC(self%mobility_mu, (3, 3, 2, nsppol, self%ntemp, self%nrta))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
          +  -  +  +  +  
          +  +  +  +  +  
             +  +  +  +  
                      + ]
    1147   [ -  +  +  -  :        3550 :  ABI_CALLOC(self%conductivity_mu, (3, 3, 2, nsppol, self%ntemp, self%nrta))
          -  +  +  -  -  
          +  +  -  -  +  
          -  +  -  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
                      + ]
    1148   [ -  +  +  -  :        1827 :  ABI_CALLOC(self%l11_mu, (3, 3, nsppol, self%ntemp, self%nrta))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
          +  -  +  +  +  
          +  +  +  +  +  
                +  +  + ]
    1149   [ -  +  +  -  :        1814 :  ABI_CALLOC(self%l12_mu, (3, 3, nsppol, self%ntemp, self%nrta))
          -  +  +  -  -  
          +  +  -  -  +  
          -  +  -  +  +  
          +  +  +  +  +  
             +  +  +  + ]
    1150   [ -  +  +  -  :        1814 :  ABI_CALLOC(self%l22_mu, (3, 3, nsppol, self%ntemp, self%nrta))
          -  +  +  -  -  
          +  +  -  -  +  
          -  +  -  +  +  
          +  +  +  +  +  
             +  +  +  + ]
    1151   [ -  +  +  -  :        1690 :  ABI_CALLOC(self%resistivity_mu, (3, 3, self%ntemp, self%nrta))
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  -  +  +  
          +  +  +  +  +  
                   +  + ]
    1152   [ +  +  +  +  :        3511 :  self%conductivity_mu=zero
          +  +  +  +  +  
                +  +  + ]
    1153   [ +  +  +  +  :        1775 :  self%l11_mu=zero
          +  +  +  +  +  
                      + ]
    1154   [ +  +  +  +  :        1775 :  self%l12_mu=zero
          +  +  +  +  +  
                      + ]
    1155   [ +  +  +  +  :        1775 :  self%l22_mu=zero
          +  +  +  +  +  
                      + ]
    1156   [ +  +  +  +  :        1651 :  self%resistivity_mu=zero
             +  +  +  + ]
    1157                 :             : ! ABI_CALLOC(self%seebeck_mu, (3, 3, 2, nsppol, self%ntemp, self%nrta))
    1158                 :             : ! ABI_CALLOC(self%kappa_mu, (3, 3, 2, nsppol, self%ntemp, self%nrta))
    1159                 :             : ! ABI_CALLOC(self%peltier_mu, (3, 3, 2, nsppol, self%ntemp, self%nrta))
    1160                 :             :  ! Compute (e/h) carriers per unit cell at the different temperatures.
    1161   [ -  +  +  -  :         300 :  ABI_CALLOC(self%n_ehst, (2, self%nsppol, self%ntemp))
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  -  +  +  
             +  +  +  +  
                      + ]
    1162                 :          13 :  call self%ebands%get_carriers(self%ntemp, self%kTmesh, self%transport_mu_e, self%n_ehst)
    1163                 :             : 
    1164                 :             :  ! Compute conductivity_mu i.e. results in which lifetimes have been computed in a consistent way
    1165                 :             :  ! with the same the Fermi level. In all the other cases, indeed, we assume that tau does not depend on ef.
    1166                 :             :  !
    1167                 :             :  ! sigma_RTA = -S e^2 / (N_k Omega) sum_\nk (v_\nk \otimes v_\nk) \tau_\nk (df^0/de_\nk)
    1168                 :             :  !
    1169                 :             :  ! with S the spin degeneracy factor.
    1170                 :             :  !
    1171                 :             :  ! TODO: Implement other tensors. Compare these results with the ones obtained with spectral sigma
    1172                 :             :  ! In principle, they should be the same, in practice the integration of sigma requires enough resolution
    1173                 :             :  ! around the band edge.
    1174                 :             :  !print *, "in RTA max velocities", maxval(abs(self%vbks))
    1175                 :          13 :  cnt = 0
    1176         [ +  + ]:          26 :  do spin=1,nsppol
    1177         [ +  + ]:        3582 :    do ik_ibz=1,nkibz
    1178                 :             :      !cnt = cnt + 1; if (mod(cnt, nprocs) /= my_rank) cycle ! MPI parallelism.
    1179                 :        3556 :      wtk = self%ebands%wtk(ik_ibz)
    1180                 :             : 
    1181         [ +  + ]:        7230 :      do ib=self%bmin,self%bmax
    1182                 :        3661 :        eig_nk = self%ebands%eig(ib, ik_ibz, spin)
    1183                 :             : 
    1184                 :             :        ! Store outer product in vv_tens
    1185         [ +  + ]:       14644 :        vr(:) = self%vbks(:, ib, ik_ibz, spin)
    1186                 :             :        ! Don't remove this if: it makes the loop a bit faster and, most importantly,
    1187                 :             :        ! it prevents intel from miscompiling the code.
    1188   [ +  +  +  +  :       14472 :        if (all(abs(vr) == zero)) cycle
                   +  + ]
    1189                 :             : 
    1190         [ +  + ]:         232 :        do ii=1,3
    1191         [ +  + ]:         754 :          do jj=1,3
    1192                 :         696 :            vv_tens(ii, jj) = vr(ii) * vr(jj)
    1193                 :             :          end do
    1194                 :             :        end do
    1195                 :             : 
    1196                 :             :        ! Symmetrize tensor.
    1197                 :             :        !print *, "intens", vv_tens
    1198   [ +  +  +  + ]:         754 :        vv_tens = cryst%symmetrize_cart_tens33(vv_tens, time_opt)
    1199                 :             :        !print *, "out_tens", vv_tens
    1200                 :             : 
    1201                 :             :        ! Multiply by the lifetime (SERTA or MRTA)
    1202         [ +  + ]:        3730 :        do irta=1,self%nrta
    1203         [ +  + ]:        4273 :          do itemp=1,self%ntemp
    1204                 :         496 :            kT = self%kTmesh(itemp)
    1205                 :         496 :            mu_e = self%transport_mu_e(itemp)
    1206         [ +  + ]:         496 :            ieh = 2; if (eig_nk >= mu_e) ieh = 1
    1207                 :         496 :            linewidth = self%linewidths(itemp, ib, ik_ibz, spin, irta)
    1208                 :             :            !print *, linewidth, wtk, occ_dfde(eig_nk, kT, mu_e), "tens", vv_tens
    1209   [ +  +  +  + ]:        6448 :            call safe_div( - wtk * vv_tens * occ_dfde(eig_nk, kT, mu_e), two * linewidth, zero, vv_tenslw)
    1210                 :             :            self%conductivity_mu(:, :, ieh, spin, itemp, irta) = self%conductivity_mu(:, :, ieh, spin, itemp, irta) &
    1211   [ +  +  +  + ]:        6448 :              + vv_tenslw(:, :)
    1212   [ +  +  +  +  :       15376 :            self%l11_mu(:, :, spin, itemp, irta) = sum(self%conductivity_mu(:,:,:, spin, itemp, irta), dim=3) !sum over ieh (holes and e-)
                   +  + ]
    1213                 :             :         !Here I implement the other onsager coefficients at the correct mu
    1214   [ +  +  +  + ]:        6448 :            call safe_div( - wtk * vv_tens * occ_dfde(eig_nk, kT, mu_e)*(eig_nk-mu_e), two * linewidth, zero, vv_tenslw)
    1215   [ +  +  +  + ]:        6448 :            self%l12_mu(:, :, spin, itemp, irta)=self%l12_mu(:, :, spin, itemp, irta)+vv_tenslw(:, :)
    1216   [ +  +  +  + ]:        6448 :            call safe_div( - wtk * vv_tens * occ_dfde(eig_nk, kT, mu_e)*(eig_nk-mu_e)**2, two * linewidth, zero, vv_tenslw)
    1217   [ +  +  +  + ]:        6564 :            self%l22_mu(:, :, spin, itemp, irta)=self%l22_mu(:, :, spin, itemp, irta)+vv_tenslw(:, :)
    1218                 :             :          end do
    1219                 :             :        end do
    1220                 :             :      end do
    1221                 :             : 
    1222                 :             :    end do ! ik_ibz
    1223                 :             :  end do ! spin
    1224                 :             : 
    1225                 :             :  !call xmpi_sum(self%conductivity_mu, comm, ierr)
    1226                 :             : 
    1227                 :             :  ! Get units conversion factor including spin degeneracy.
    1228                 :          13 :  max_occ = two / (self%nspinor * self%nsppol)
    1229                 :          13 :  fact0 = max_occ * (siemens_SI / Bohr_meter / cryst%ucvol) / 100
    1230   [ +  +  +  +  :        3511 :  self%conductivity_mu = fact0 * self%conductivity_mu  ! siemens cm^-1
          +  +  +  +  +  
                +  +  + ]
    1231   [ +  +  +  +  :        1775 :  self%l11_mu = max_occ * self%l11_mu
          +  +  +  +  +  
                      + ]
    1232   [ +  +  +  +  :        1775 :  self%l12_mu = max_occ * self%l12_mu
          +  +  +  +  +  
                      + ]
    1233   [ +  +  +  +  :        1775 :  self%l22_mu = max_occ * self%l22_mu
          +  +  +  +  +  
                      + ]
    1234                 :             : 
    1235                 :             : !Same for resistivity_mu (at correct mu)
    1236                 :             : 
    1237                 :             : ! ABI_MALLOC(self%resistivity_mu, (3, 3, self%ntemp, self%nrta))
    1238         [ +  + ]:          39 :  do irta=1,self%nrta
    1239         [ +  + ]:         163 :   do itemp=1,self%ntemp
    1240                 :             : 
    1241   [ +  +  +  +  :        2728 :     work_33 = sum(self%l11_mu(:,:,:,itemp,irta), dim=3) !sum over spins
                   +  + ]
    1242   [ +  +  +  + ]:        1612 :     work_33 = work_33*fact0
    1243   [ +  +  +  + ]:        1612 :     call inv33(work_33, mat33); mat33 = 1e+6_dp * mat33
    1244   [ +  +  +  + ]:        1638 :     self%resistivity_mu(:, :, itemp, irta) = mat33
    1245                 :             :   end do
    1246                 :             :  end do
    1247                 :             : 
    1248                 :             : 
    1249                 :             :  !TODO: implement for mobility as well (verify)
    1250                 :             :  ! Scale by the carrier concentration
    1251                 :             :  fact = 100**3 / e_Cb
    1252         [ +  + ]:          39 :  do irta=1,self%nrta
    1253         [ +  + ]:          65 :    do spin=1,nsppol
    1254         [ +  + ]:         176 :      do itemp=1,self%ntemp
    1255         [ +  + ]:         398 :        do ieh=1,2 ! e/h
    1256                 :             :          call safe_div(fact * self%conductivity_mu(:,:,ieh,spin,itemp, irta), &
    1257                 :             :                        self%n_ehst(ieh, spin, itemp) / cryst%ucvol / Bohr_meter**3, zero, &
    1258   [ +  +  +  + ]:        3348 :                        self%mobility_mu(:,:,ieh,spin,itemp,irta))
    1259                 :             :        end do
    1260                 :             :      end do
    1261                 :             :    end do
    1262                 :             :  end do
    1263                 :             : 
    1264                 :          13 :  call cwtime_report(" compute_rta_mobility", cpu, wall, gflops)
    1265                 :             : 
    1266                 :          26 : end subroutine compute_rta_mobility
    1267                 :             : !!***
    1268                 :             : 
    1269                 :             : !----------------------------------------------------------------------
    1270                 :             : 
    1271                 :             : !!****f* m_rta/rta_ncwrite
    1272                 :             : !! NAME
    1273                 :             : !! rta_ncwrite
    1274                 :             : !!
    1275                 :             : !! FUNCTION
    1276                 :             : !!
    1277                 :             : !! INPUTS
    1278                 :             : !! cryst<crystal_t>=Crystalline structure
    1279                 :             : !! dtset<dataset_type>=All input variables for this dataset.
    1280                 :             : !! ncid=Netcdf file handle.
    1281                 :             : !!
    1282                 :             : !! SOURCE
    1283                 :             : 
    1284                 :          13 : subroutine rta_ncwrite(self, cryst, dtset, ncid)
    1285                 :             : 
    1286                 :             : !Arguments --------------------------------------
    1287                 :             :  class(rta_t),intent(in) :: self
    1288                 :             :  type(crystal_t),intent(in) :: cryst
    1289                 :             :  type(dataset_type),intent(in) :: dtset
    1290                 :             :  integer,intent(in) :: ncid
    1291                 :             : 
    1292                 :             : !Local variables --------------------------------
    1293                 :             :  integer :: ncerr, ii
    1294                 :             :  real(dp) :: cpu, wall, gflops
    1295                 :          26 :  real(dp) :: work(dtset%nsppol)
    1296                 :             : !************************************************************************
    1297                 :             : 
    1298                 :          13 :  call cwtime(cpu, wall, gflops, "start")
    1299                 :             : 
    1300                 :             :  ! Write to netcdf file
    1301         [ -  + ]:          13 :  NCF_CHECK(cryst%ncwrite(ncid))
    1302         [ -  + ]:          13 :  NCF_CHECK(self%ebands%ncwrite(ncid))
    1303         [ -  + ]:          13 :  NCF_CHECK(self%edos%ncwrite(ncid))
    1304                 :             : 
    1305                 :             :  !nctk_copy from sigeph?
    1306                 :             :  !    nctkarr_t("eph_ngqpt_fine", "int", "three"), &
    1307                 :             : 
    1308                 :             :  ncerr = nctk_def_dims(ncid, [ &
    1309                 :             :     nctkdim_t("ntemp", self%ntemp), nctkdim_t("nrta", self%nrta), nctkdim_t("nsppol", self%nsppol), &
    1310                 :             :     nctkdim_t("nkcalc", self%nkcalc), nctkdim_t("nkibz", self%ebands%nkpt) &
    1311         [ +  + ]:          78 :  ], defmode=.True.)
    1312         [ -  + ]:          13 :  NCF_CHECK(ncerr)
    1313                 :             : 
    1314                 :             :  ncerr = nctk_def_arrays(ncid, [ &
    1315                 :             :     nctkarr_t('transport_ngkpt', "int", "three"), &
    1316                 :             :     nctkarr_t('sigma_erange', "dp", "two"), &
    1317                 :             :     nctkarr_t("kcalc2ibz", "int", "nkcalc, six"), &
    1318                 :             :     nctkarr_t("kcalc2ebands", "int", "six, nkcalc"), &
    1319                 :             :     nctkarr_t("kibz", "dp", "three, nkibz"), &
    1320                 :             :     nctkarr_t('kTmesh', "dp", "ntemp"), &
    1321                 :             :     nctkarr_t('transport_mu_e', "dp", "ntemp"), &
    1322                 :             :     nctkarr_t('n_ehst', "dp", "two, nsppol, ntemp"), &
    1323                 :             :     nctkarr_t('eph_mu_e', "dp", "ntemp"), &
    1324                 :             :     nctkarr_t('vb_max', "dp", "nsppol"), &
    1325                 :             :     nctkarr_t('cb_min', "dp", "nsppol"), &
    1326                 :             :     nctkarr_t('vv_dos', "dp", "edos_nw, three, three, nsppol"), &
    1327                 :             :     nctkarr_t('vvtau_dos', "dp", "edos_nw, three, three, ntemp, nsppol, nrta"), &
    1328                 :             :     nctkarr_t('tau_dos', "dp", "edos_nw, ntemp, nsppol, nrta"), &
    1329                 :             :     nctkarr_t('L0', "dp", "three, three, edos_nw, nsppol, ntemp, nrta"), &
    1330                 :             :     nctkarr_t('L1', "dp", "three, three, edos_nw, nsppol, ntemp, nrta"), &
    1331                 :             :     nctkarr_t('L2', "dp", "three, three, edos_nw, nsppol, ntemp, nrta"), &
    1332                 :             :     nctkarr_t('sigma', "dp", "three, three, edos_nw, nsppol, ntemp, nrta"), &
    1333                 :             :     nctkarr_t('kappa', "dp", "three, three, edos_nw, nsppol, ntemp, nrta"), &
    1334                 :             :     nctkarr_t('zte', "dp", "three, three, edos_nw, nsppol, ntemp, nrta"), &
    1335                 :             :     nctkarr_t('seebeck', "dp", "three, three, edos_nw, nsppol, ntemp, nrta"), &
    1336                 :             :     nctkarr_t('pi', "dp", "three, three, edos_nw, nsppol, ntemp, nrta"), &
    1337                 :             :     nctkarr_t('mobility', "dp", "three, three, edos_nw, ntemp, two, nsppol, nrta"), &
    1338                 :             :     nctkarr_t('conductivity', "dp", "three, three, ntemp, nsppol, nrta"), &
    1339                 :             :     nctkarr_t('resistivity', "dp", "three, three, ntemp, nrta"), &
    1340                 :             :     nctkarr_t('N', "dp", "edos_nw, ntemp, two"), &
    1341                 :             :     !nctkarr_t('conductivity_mu',"dp", "three, three, two, nsppol, ntemp, nrta")], &
    1342                 :             :     nctkarr_t('mobility_mu', "dp", "three, three, two, nsppol, ntemp, nrta")], &
    1343         [ +  + ]:         364 :  defmode=.True.)
    1344         [ -  + ]:          13 :  NCF_CHECK(ncerr)
    1345                 :             : 
    1346         [ +  + ]:          26 :  ncerr = nctk_def_iscalars(ncid, [character(len=nctk_slen) :: "assume_gap"])
    1347         [ -  + ]:          13 :  NCF_CHECK(ncerr)
    1348                 :             :  ncerr = nctk_def_dpscalars(ncid, [character(len=nctk_slen) :: &
    1349         [ +  + ]:          65 :     "eph_extrael", "eph_fermie", "transport_extrael", "transport_fermie"])
    1350         [ -  + ]:          13 :  NCF_CHECK(ncerr)
    1351                 :             : 
    1352                 :             :  ! Write data.
    1353         [ +  + ]:          13 :  ii = 0; if (self%assume_gap) ii = 1
    1354   [ +  +  +  + ]:          39 :  ncerr = nctk_write_iscalars(ncid, [character(len=nctk_slen) :: "assume_gap"], [ii], datamode=.True.)
    1355                 :             : 
    1356                 :             :  ncerr = nctk_write_dpscalars(ncid, [character(len=nctk_slen) :: &
    1357                 :             :    "eph_extrael", "eph_fermie", "transport_extrael", "transport_fermie"], &
    1358   [ +  +  +  + ]:         117 :    [self%eph_extrael, self%eph_fermie, self%transport_extrael, self%transport_fermie])
    1359         [ -  + ]:          13 :  NCF_CHECK(ncerr)
    1360                 :             : 
    1361         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "transport_ngkpt"), dtset%transport_ngkpt))
    1362         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "sigma_erange"), dtset%sigma_erange))
    1363         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "kcalc2ibz"), self%kcalc2ibz))
    1364         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "kcalc2ebands"), self%kcalc2ebands))
    1365         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "kibz"), self%ebands%kptns))
    1366         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "kTmesh"), self%kTmesh))
    1367         [ +  + ]:          13 :  if (self%assume_gap) then
    1368         [ -  + ]:          12 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "vb_max"), self%gaps%vb_max))
    1369         [ -  + ]:          12 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "cb_min"), self%gaps%cb_min))
    1370                 :             :  else
    1371                 :             :    ! Set vbm and cbm to fermie if metal.
    1372         [ +  + ]:           2 :    work(:) = self%ebands%fermie
    1373         [ -  + ]:           1 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "vb_max"), work))
    1374         [ -  + ]:           1 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "cb_min"), work))
    1375                 :             :  end if
    1376         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "eph_mu_e"), self%eph_mu_e))
    1377         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "transport_mu_e"), self%transport_mu_e))
    1378         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "n_ehst"), self%n_ehst))
    1379         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "vv_dos"), self%vv_dos))
    1380         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "vvtau_dos"),  self%vvtau_dos))
    1381         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "tau_dos"),  self%tau_dos))
    1382         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "L0"), self%l0))
    1383         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "L1"), self%l1))
    1384         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "L2"), self%l2))
    1385         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "sigma"),   self%sigma))
    1386         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "kappa"),   self%kappa))
    1387         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "zte"),   self%zte))
    1388         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "seebeck"), self%seebeck))
    1389         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "pi"),      self%pi))
    1390         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "N"), self%n))
    1391         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "mobility"), self%mobility))
    1392         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "conductivity"), self%conductivity))
    1393         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "resistivity"), self%resistivity))
    1394         [ -  + ]:          13 :  NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "mobility_mu"), self%mobility_mu))
    1395                 :             :  !NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "conductivity_mu"), self%conductivity_mu))
    1396                 :             :  !NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "resistivity_mu"), self%resistivity_mu))
    1397                 :             : 
    1398                 :          13 :  call cwtime_report(" rta_ncwrite", cpu, wall, gflops)
    1399                 :             : 
    1400                 :          13 : end subroutine rta_ncwrite
    1401                 :             : !!***
    1402                 :             : 
    1403                 :             : !----------------------------------------------------------------------
    1404                 :             : 
    1405                 :             : !!****f* m_rta/print_rta_txt_files
    1406                 :             : !! NAME
    1407                 :             : !! print_rta_txt_files
    1408                 :             : !!
    1409                 :             : !! FUNCTION
    1410                 :             : !!
    1411                 :             : !! INPUTS
    1412                 :             : !! cryst<crystal_t>=Crystalline structure
    1413                 :             : !! dtset<dataset_type>=All input variables for this dataset.
    1414                 :             : !! dtfil<datafiles_type>=variables related to files.
    1415                 :             : !!
    1416                 :             : !! SOURCE
    1417                 :             : 
    1418                 :          13 : subroutine print_rta_txt_files(self, cryst, dtset, dtfil)
    1419                 :             : 
    1420                 :             : !Arguments --------------------------------------
    1421                 :             :  class(rta_t),intent(in) :: self
    1422                 :             :  type(crystal_t),intent(in) :: cryst
    1423                 :             :  type(dataset_type),intent(in) :: dtset
    1424                 :             :  type(datafiles_type),intent(in) :: dtfil
    1425                 :             : 
    1426                 :             : !Local variables --------------------------------
    1427                 :             :  integer :: itemp, spin, irta, ii, nsp
    1428                 :             :  real(dp) :: TKelv
    1429                 :             :  character(len=500) :: msg, pre, rta_type
    1430                 :             :  integer :: units(2)
    1431                 :             :  character(len=2) :: components(3)
    1432                 :             :  real(dp) :: mat33(3,3),  work33(3,3)
    1433                 :             : !************************************************************************
    1434                 :             : 
    1435         [ +  + ]:          39 :  units = [std_out, ab_out]
    1436                 :          13 :  call wrtout(units, ch10//' Transport (RTA) calculation results, chemical potential adjusted with T:', newlines=1)
    1437         [ +  + ]:          52 :  components = ["xx", "yy", "zz"]
    1438                 :             : 
    1439         [ +  + ]:          39 :  do irta=1,self%nrta
    1440         [ +  + ]:          26 :    if (irta == 1) rta_type = "SERTA"
    1441         [ +  + ]:          26 :    if (irta == 2) rta_type = "MRTA"
    1442                 :             : 
    1443         [ +  + ]:          26 :    if (self%assume_gap) then
    1444                 :             :      ! SemiConductor
    1445         [ +  + ]:          96 :      do ii=1,3
    1446                 :          72 :        call wrtout(units, sjoin(" Cartesian component of", rta_type, "mobility tensor:", components(ii)))
    1447                 :          72 :        write(msg, "(a16,a32,a32)") 'Temperature [K]', 'e/h density [cm^-3]', 'e/h mobility [cm^2/Vs]'
    1448                 :          72 :        call wrtout(units, msg)
    1449                 :             : 
    1450         [ +  + ]:         144 :        do spin=1,self%nsppol
    1451         [ -  + ]:          72 :          if (self%nsppol == 2) call wrtout(units, sjoin(" For spin:", stoa(spin)), newlines=1)
    1452                 :             : 
    1453         [ +  + ]:         504 :          do itemp=1,self%ntemp
    1454                 :             :            write(msg,"(f16.2,2e16.2,2f16.2)") &
    1455                 :         360 :              self%kTmesh(itemp) / kb_HaK, &
    1456                 :         360 :              self%n_ehst(1, spin, itemp) / cryst%ucvol / Bohr_cm**3, &
    1457                 :         360 :              self%n_ehst(2, spin, itemp) / cryst%ucvol / Bohr_cm**3, &
    1458                 :         360 :              self%mobility_mu(ii, ii, 1, spin, itemp, irta), &
    1459                 :         720 :              self%mobility_mu(ii, ii, 2, spin, itemp, irta)
    1460                 :         432 :            call wrtout(units, msg)
    1461                 :             :          end do ! itemp
    1462                 :             :        end do ! spin
    1463                 :          96 :        call wrtout(units, ch10)
    1464                 :             :      end do ! ii
    1465                 :             : 
    1466                 :             :    else
    1467                 :             :      ! Metals. Print conductivity (spin resolved) and resistivity (no spin resolved)
    1468                 :             : !    do ii=1,2
    1469                 :             : !      if (ii == 1) msg = sjoin(" Conductivity [Siemens cm^-1] using ", rta_type, "approximation")
    1470                 :             : !      if (ii == 2) msg = sjoin(" Resistivity [micro-Ohm cm] using ", rta_type, "approximation")
    1471                 :             : !      call wrtout(units, msg)
    1472                 :             : !
    1473                 :             : !      nsp = self%nsppol; if (ii == 2) nsp = 1
    1474                 :             : !      do spin=1,nsp
    1475                 :             : !        if (nsp == 2) call wrtout(units, sjoin(" For spin:", stoa(spin)), newlines=1)
    1476                 :             : !        write(msg, "(4a16)") 'Temperature (K)', 'xx', 'yy', 'zz'
    1477                 :             : !        call wrtout(units, msg)
    1478                 :             : !        do itemp=1,self%ntemp
    1479                 :             : !          if (ii == 1) then
    1480                 :             : !            mat33 = self%conductivity(:,:,itemp,spin,irta)
    1481                 :             : !          else
    1482                 :             : !            mat33 = self%resistivity(:,:,itemp,irta)
    1483                 :             : !          end if
    1484                 :             : !          write(msg,"(f16.2,3e16.6)") self%kTmesh(itemp) / kb_HaK, mat33(1,1), mat33(2,2), mat33(3,3)
    1485                 :             : !          call wrtout(units, msg)
    1486                 :             : !        end do !itemp
    1487                 :             : !      end do !spin
    1488                 :             : !      call wrtout(units, ch10)
    1489                 :             : !    end do
    1490                 :             : 
    1491                 :             :      !For coefficients calculated at exact mu (i.e for mu calculated at exact temp.):
    1492                 :             :      !TODO: do the same for SM and thus mobility
    1493                 :             : 
    1494         [ +  + ]:           6 :      do ii=1,2
    1495   [ +  +  +  - ]:           4 :        if (ii == 1) msg = sjoin(" Conductivity [Siemens cm^-1] using ", rta_type, "approximation")
    1496   [ +  +  +  - ]:           4 :        if (ii == 2) msg = sjoin(" Resistivity [micro-Ohm cm] using ", rta_type, "approximation")
    1497                 :           4 :        call wrtout(units, msg)
    1498                 :             : 
    1499         [ +  + ]:          12 :        do itemp=1, self%ntemp
    1500         [ +  + ]:           8 :          nsp = self%nsppol; if (ii == 2) nsp = 1
    1501         [ +  + ]:          20 :          do spin=1,nsp
    1502         [ -  + ]:           8 :            if (nsp == 2) call wrtout(units, sjoin(" For spin:", stoa(spin)), newlines=1)
    1503                 :           8 :            write(msg, "(4a16)") 'Temperature (K)', 'xx', 'yy', 'zz'
    1504                 :           8 :            call wrtout(units, msg)
    1505                 :             : 
    1506         [ +  + ]:           8 :            if (ii == 1) then
    1507   [ +  +  +  +  :         124 :              mat33 = sum(self%conductivity_mu(:,:,:,spin, itemp, irta), dim=3)
                   +  + ]
    1508                 :             :            else
    1509   [ +  +  +  + ]:          52 :              mat33 = self%resistivity_mu(:,:,itemp,irta)
    1510                 :             :            end if
    1511                 :           8 :            write(msg,"(f16.2,3e16.6)") self%kTmesh(itemp) / kb_HaK, mat33(1,1), mat33(2,2), mat33(3,3)
    1512                 :          16 :            call wrtout(units, msg)
    1513                 :             :          end do !spin
    1514                 :             :        end do !itemp
    1515                 :           6 :        call wrtout(units, ch10)
    1516                 :             :      end do
    1517                 :             :    end if
    1518                 :             : 
    1519         [ +  - ]:          26 :    msg = sjoin(" Seebeck [Volts / Kelvin] using ", rta_type, "approximation")
    1520                 :          26 :    call wrtout(units, msg)
    1521         [ +  + ]:         150 :    do itemp=1, self%ntemp
    1522                 :             :      !TODO : what is the following line? Resets 0 Kelvin to 1 Kelvin minimum T??? a bit arbitrary. Should handle T=0 more cleanly
    1523         [ +  + ]:         124 :      TKelv = self%kTmesh(itemp) / kb_HaK; if (TKelv < one) Tkelv = one
    1524                 :         124 :      nsp = self%nsppol;
    1525         [ +  + ]:         274 :      do spin=1,nsp
    1526         [ -  + ]:         124 :        if (nsp == 2) call wrtout(units, sjoin(" For spin:", stoa(spin)), newlines=1)
    1527                 :         124 :        write(msg, "(4a16)") 'Temperature (K)', 'xx', 'yy', 'zz'
    1528                 :         124 :        call wrtout(units, msg)
    1529                 :         124 :        call inv33(self%l11_mu(:, :, spin, itemp, irta), work33)
    1530   [ +  -  +  +  :        9796 :        mat33 = - (volt_SI / TKelv) * matmul(work33, self%l12_mu(:,:,spin,itemp,irta))
          +  +  +  +  +  
          -  +  -  +  +  
                   +  + ]
    1531                 :         124 :        write(msg,"(f16.2,3e16.6)") TKelv, mat33(1,1), mat33(2,2), mat33(3,3)
    1532                 :         248 :        call wrtout(units, msg)
    1533                 :             :      end do !spin
    1534                 :             :    end do !itemp
    1535                 :          26 :    call wrtout(units, ch10)
    1536                 :             : 
    1537         [ +  - ]:          26 :    msg = sjoin(" Kappa [W/m*K] using ", rta_type, "approximation")
    1538                 :          26 :    call wrtout(units, msg)
    1539         [ +  + ]:         150 :    do itemp=1, self%ntemp
    1540         [ +  + ]:         124 :      TKelv = self%kTmesh(itemp) / kb_HaK; if (TKelv < one) Tkelv = one
    1541                 :         124 :      nsp = self%nsppol;
    1542         [ +  + ]:         274 :      do spin=1,nsp
    1543         [ -  + ]:         124 :        if (nsp == 2) call wrtout(units, sjoin(" For spin:", stoa(spin)), newlines=1)
    1544                 :         124 :        write(msg, "(4a16)") 'Temperature (K)', 'xx', 'yy', 'zz'
    1545                 :         124 :        call wrtout(units, msg)
    1546                 :         124 :          call inv33(self%l11_mu(:, :, spin, itemp, irta), work33)
    1547   [ -  +  +  -  :       26412 :          mat33 = + (volt_SI**2 * (siemens_SI / Bohr_meter / cryst%ucvol) / TKelv) * (self%l22_mu(:,:,spin,itemp,irta) - matmul(self%l12_mu(:,:,spin,itemp,irta),matmul(work33,self%l12_mu(:,:,spin,itemp,irta))))
          +  -  +  -  -  
          +  -  +  +  +  
          +  +  +  +  +  
          +  +  +  +  -  
          +  -  +  -  +  
          +  +  +  +  +  
          +  -  +  -  +  
          -  +  -  +  -  
             +  +  +  + ]
    1548                 :         124 :        write(msg,"(f16.2,3e16.6)") TKelv, mat33(1,1), mat33(2,2), mat33(3,3)
    1549                 :         248 :        call wrtout(units, msg)
    1550                 :             :      end do !spin
    1551                 :             :    end do !itemp
    1552                 :          26 :    call wrtout(units, ch10)
    1553                 :             : 
    1554         [ +  - ]:          26 :    msg = sjoin(" Peltier [Volts] using ", rta_type, "approximation")
    1555                 :          26 :    call wrtout(units, msg)
    1556         [ +  + ]:         150 :    do itemp=1, self%ntemp
    1557         [ +  + ]:         124 :      TKelv = self%kTmesh(itemp) / kb_HaK; if (TKelv < one) Tkelv = one
    1558                 :         124 :      nsp = self%nsppol;
    1559         [ +  + ]:         274 :      do spin=1,nsp
    1560         [ -  + ]:         124 :        if (nsp == 2) call wrtout(units, sjoin(" For spin:", stoa(spin)), newlines=1)
    1561                 :         124 :        write(msg, "(4a16)") 'Temperature (K)', 'xx', 'yy', 'zz'
    1562                 :         124 :        call wrtout(units, msg)
    1563                 :         124 :          call inv33(self%l11_mu(:, :, spin, itemp, irta), work33)
    1564   [ +  -  +  +  :        9920 :          mat33 = - volt_SI * matmul(self%l12_mu(:,:,spin,itemp,irta), work33)
          +  +  +  +  +  
          -  +  -  +  +  
                   +  + ]
    1565                 :         124 :        write(msg,"(f16.2,3e16.6)") TKelv, mat33(1,1), mat33(2,2), mat33(3,3)
    1566                 :         248 :        call wrtout(units, msg)
    1567                 :             :      end do !spin
    1568                 :             :    end do !itemp
    1569                 :          39 :    call wrtout(units, ch10)
    1570                 :             : 
    1571                 :             : 
    1572                 :             : 
    1573                 :             :  end do ! irta
    1574                 :             : 
    1575         [ +  + ]:          39 :  do irta=1,self%nrta
    1576                 :          13 :    select case (irta)
    1577                 :             :    case (1)
    1578                 :          13 :      pre = "_SERTA"
    1579                 :             :    case (2)
    1580                 :          13 :      pre = "_MRTA"
    1581                 :             :    case default
    1582      [ +  +  - ]:          26 :      ABI_ERROR(sjoin("Don't know how to handle irta:", itoa(irta)))
    1583                 :             :    end select
    1584                 :          26 :    call self%write_tensor(dtset, irta, "sigma", self%sigma(:,:,:,:,:,irta), strcat(dtfil%filnam_ds(4), pre, "_SIGMA"))
    1585                 :          26 :    call self%write_tensor(dtset, irta, "seebeck", self%seebeck(:,:,:,:,:,irta), strcat(dtfil%filnam_ds(4), pre, "_SBK"))
    1586                 :          26 :    call self%write_tensor(dtset, irta, "kappa", self%kappa(:,:,:,:,:,irta), strcat(dtfil%filnam_ds(4), pre, "_KAPPA"))
    1587                 :          26 :    call self%write_tensor(dtset, irta, "zte", self%zte(:,:,:,:,:,irta), strcat(dtfil%filnam_ds(4), pre, "_ZTE"))
    1588                 :          39 :    call self%write_tensor(dtset, irta, "pi", self%pi(:,:,:,:,:,irta), strcat(dtfil%filnam_ds(4), pre, "_PI"))
    1589                 :             :  end do
    1590                 :             : 
    1591                 :          13 : end subroutine print_rta_txt_files
    1592                 :             : !!***
    1593                 :             : 
    1594                 :             : !----------------------------------------------------------------------
    1595                 :             : 
    1596                 :             : !!****f* m_rta/write_tensor
    1597                 :             : !! NAME
    1598                 :             : !!
    1599                 :             : !! FUNCTION
    1600                 :             : !!
    1601                 :             : !! INPUTS
    1602                 :             : !!
    1603                 :             : !! SOURCE
    1604                 :             : 
    1605         [ -  + ]:         130 : subroutine write_tensor(self, dtset, irta, header, values, path)
    1606                 :             : 
    1607                 :             : !Arguments --------------------------------------
    1608                 :             :  class(rta_t),intent(in) :: self
    1609                 :             :  type(dataset_type),intent(in) :: dtset
    1610                 :             :  integer,intent(in) :: irta
    1611                 :             :  character(len=*),intent(in) :: header
    1612                 :             :  real(dp),intent(in) :: values(:,:,:,:,:)
    1613                 :             :  character(len=*),intent(in) :: path
    1614                 :             : 
    1615                 :             : !Local variables --------------------------------
    1616                 :             :  integer :: itemp, iw, ount
    1617                 :             :  character(len=500) :: msg, rta_type
    1618                 :         130 :  real(dp),allocatable :: tmp_values(:,:,:,:,:)
    1619                 :             : !************************************************************************
    1620                 :             : 
    1621         [ -  + ]:         130 :  if (open_file(trim(path), msg, newunit=ount, form="formatted", action="write", status='unknown') /= 0) then
    1622                 :           0 :    ABI_ERROR(msg)
    1623                 :             :  end if
    1624                 :             : 
    1625         [ +  + ]:         130 :  if (irta == 1) rta_type = "RTA type: Self-energy relaxation time approximation (SERTA)"
    1626         [ +  + ]:         130 :  if (irta == 2) rta_type = "RTA type: Momentum relaxation time approximation (MRTA)"
    1627                 :             : 
    1628                 :             :  ! write header
    1629                 :         130 :  write(ount, "(2a)")"# ", trim(header)
    1630                 :         130 :  write(ount, "(2a)")"# ", trim(rta_type)
    1631                 :             :  ! TODO: Units ?
    1632                 :         130 :  write(ount, "(a, 3(i0, 1x))")"#", dtset%transport_ngkpt
    1633                 :         130 :  write(ount, "(a)")"#"
    1634                 :             : 
    1635                 :             :  ! This to improve portability of the unit tests.
    1636                 :         130 :  call alloc_copy(values, tmp_values)
    1637   [ +  +  +  +  :     1673170 :  where (abs(values) > tol30)
          +  +  +  +  +  
                +  +  + ]
    1638                 :             :    tmp_values = values
    1639                 :             :  else where
    1640                 :             :    tmp_values = zero
    1641                 :             :  end where
    1642                 :             : 
    1643                 :             :  ! (nw, 3, 3, nsppol, ntemp)
    1644         [ +  - ]:         130 :  if (self%nsppol == 1) then
    1645         [ +  + ]:         750 :    do itemp=1, self%ntemp
    1646                 :         620 :      write(ount, "(/, a, 1x, f16.2)")"# T = ", self%kTmesh(itemp) / kb_HaK
    1647                 :         620 :      write(ount, "(a)")"# Energy [Ha], (xx, yx, zx, xy, yy, zy, xz, yz, zz) Cartesian components of tensor."
    1648         [ +  + ]:      129350 :      do iw=1,self%nw
    1649                 :      129220 :        write(ount, "(10(es16.6))")self%edos%mesh(iw), tmp_values(:, :, iw, 1, itemp)
    1650                 :             :      end do
    1651                 :             :    end do
    1652                 :         130 :   write(ount, "(a)")""
    1653                 :             :  else
    1654         [ #  # ]:           0 :    do itemp=1, self%ntemp
    1655                 :           0 :      write(ount, "(/, a, 1x, f16.2)")"# T = ", self%kTmesh(itemp) / kb_HaK
    1656                 :             :      write(ount, "(a)") &
    1657                 :           0 :        "# Energy [Ha], (xx, yx, zx, xy, yy, zy, xz, yz, zz) Cartesian components of tensor for spin up followed by spin down."
    1658         [ #  # ]:           0 :      do iw=1,self%nw
    1659                 :           0 :        write(ount, "(19(es16.6))")self%edos%mesh(iw), tmp_values(:, :, iw, 1, itemp), tmp_values(:, :, iw, 2, itemp)
    1660                 :             :      end do
    1661                 :             :    end do
    1662                 :           0 :   write(ount, "(a)")""
    1663                 :             :  end if
    1664                 :             : 
    1665                 :         130 :  close(ount)
    1666                 :             : 
    1667         [ -  + ]:         130 :  ABI_FREE(tmp_values)
    1668                 :             : 
    1669                 :         130 : end subroutine write_tensor
    1670                 :             : !!***
    1671                 :             : 
    1672                 :             : !----------------------------------------------------------------------
    1673                 :             : 
    1674                 :             : !!****f* m_rta/rta_free
    1675                 :             : !! NAME
    1676                 :             : !! rta_free
    1677                 :             : !!
    1678                 :             : !! FUNCTION
    1679                 :             : !!  Free dynamic memory.
    1680                 :             : !!
    1681                 :             : !! INPUTS
    1682                 :             : !!
    1683                 :             : !! SOURCE
    1684                 :             : 
    1685                 :          13 : subroutine rta_free(self)
    1686                 :             : 
    1687                 :             : !Arguments --------------------------------------
    1688                 :             :  class(rta_t),intent(inout) :: self
    1689                 :             : 
    1690         [ +  - ]:          13 :  ABI_SFREE(self%n)
    1691         [ +  - ]:          13 :  ABI_SFREE(self%vv_dos)
    1692         [ +  - ]:          13 :  ABI_SFREE(self%vvtau_dos)
    1693         [ +  - ]:          13 :  ABI_SFREE(self%tau_dos)
    1694         [ +  - ]:          13 :  ABI_SFREE(self%bstart_ks)
    1695         [ +  - ]:          13 :  ABI_SFREE(self%bstop_ks)
    1696         [ +  - ]:          13 :  ABI_SFREE(self%nbcalc_ks)
    1697         [ +  - ]:          13 :  ABI_SFREE(self%kcalc2ibz)
    1698         [ +  - ]:          13 :  ABI_SFREE(self%kcalc2ebands)
    1699         [ +  - ]:          13 :  ABI_SFREE(self%kTmesh)
    1700         [ +  - ]:          13 :  ABI_SFREE(self%eminmax_spin)
    1701         [ +  - ]:          13 :  ABI_SFREE(self%eph_mu_e)
    1702         [ +  - ]:          13 :  ABI_SFREE(self%transport_mu_e)
    1703         [ +  - ]:          13 :  ABI_SFREE(self%vbks)
    1704         [ +  - ]:          13 :  ABI_SFREE(self%linewidths)
    1705         [ +  - ]:          13 :  ABI_SFREE(self%l0)
    1706         [ +  - ]:          13 :  ABI_SFREE(self%l1)
    1707         [ +  - ]:          13 :  ABI_SFREE(self%l2)
    1708         [ +  - ]:          13 :  ABI_SFREE(self%sigma)
    1709         [ +  - ]:          13 :  ABI_SFREE(self%mobility)
    1710         [ +  - ]:          13 :  ABI_SFREE(self%conductivity)
    1711         [ +  - ]:          13 :  ABI_SFREE(self%resistivity)
    1712         [ +  - ]:          13 :  ABI_SFREE(self%seebeck)
    1713         [ +  - ]:          13 :  ABI_SFREE(self%kappa)
    1714         [ +  - ]:          13 :  ABI_SFREE(self%zte)
    1715         [ +  - ]:          13 :  ABI_SFREE(self%pi)
    1716         [ +  - ]:          13 :  ABI_SFREE(self%mobility_mu)
    1717         [ +  - ]:          13 :  ABI_SFREE(self%conductivity_mu)
    1718         [ +  - ]:          13 :  ABI_SFREE(self%resistivity_mu)
    1719         [ +  - ]:          13 :  ABI_SFREE(self%l11_mu)
    1720         [ +  - ]:          13 :  ABI_SFREE(self%l12_mu)
    1721         [ +  - ]:          13 :  ABI_SFREE(self%l22_mu)
    1722         [ +  - ]:          13 :  ABI_SFREE(self%n_ehst)
    1723                 :             : 
    1724                 :          13 :  call self%ebands%free()
    1725                 :          13 :  call self%gaps%free()
    1726                 :          13 :  call self%edos%free()
    1727                 :             : 
    1728                 :          13 : end subroutine rta_free
    1729                 :             : !!***
    1730                 :             : 
    1731                 :             : !----------------------------------------------------------------------
    1732                 :             : 
    1733                 :             : !!****f* m_rta/ibte_driver
    1734                 :             : !! NAME
    1735                 :             : !! ibte_driver
    1736                 :             : !!
    1737                 :             : !! FUNCTION
    1738                 :             : !! Driver to compute transport properties within the IBTE.
    1739                 :             : !!
    1740                 :             : !! INPUTS
    1741                 :             : !! dtfil<datafiles_type>=variables related to files.
    1742                 :             : !! ngfftc(18)=Coarse FFT mesh
    1743                 :             : !! dtset<dataset_type>=All input variables for this dataset.
    1744                 :             : !! ebands<ebands_t>=The GS KS band structure (energies, occupancies, k-weights...)
    1745                 :             : !! cryst<crystal_t>=Crystalline structure
    1746                 :             : !! pawtab(ntypat*usepaw)<pawtab_type>=Paw tabulated starting data.
    1747                 :             : !! psps<pseudopotential_type>=Variables related to pseudopotentials.
    1748                 :             : !! comm=MPI communicator.
    1749                 :             : !!
    1750                 :             : !! SOURCE
    1751                 :             : 
    1752                 :           1 : subroutine ibte_driver(dtfil, ngfftc, dtset, ebands, cryst, pawtab, psps, comm)
    1753                 :             : 
    1754                 :             : !Arguments ------------------------------------
    1755                 :             : !scalars
    1756                 :             :  integer, intent(in) :: comm
    1757                 :             :  type(datafiles_type),intent(in) :: dtfil
    1758                 :             :  type(dataset_type),intent(in) :: dtset
    1759                 :             :  type(crystal_t),intent(in) :: cryst
    1760                 :             :  type(ebands_t),intent(in) :: ebands
    1761                 :             :  type(pseudopotential_type),intent(in) :: psps
    1762                 :             : !arrays
    1763                 :             :  integer,intent(in) :: ngfftc(18)
    1764                 :             :  type(pawtab_type),intent(in) :: pawtab(psps%ntypat*psps%usepaw)
    1765                 :             : 
    1766                 :             : !Local variables ------------------------------
    1767                 :             :  integer,parameter :: master = 0
    1768                 :             :  integer :: iet, max_et
    1769                 :             :  integer :: spin, ikcalc, nkcalc, nbsum, nbcalc, itemp, iter, ierr, bsize
    1770                 :             :  integer :: nkibz, nsppol, band_k, ik_ibz, bmin, bmax, band_sum, ntemp, ii, jj, iq_sum, nsp
    1771                 :             :  integer :: ikq_ibz, isym_kq, trev_kq, cnt, tag, nprocs, receiver, my_rank, isym, itime, isym_lgk
    1772                 :             :  integer :: ncid, grp_ncid, ncerr
    1773                 :             :  real(dp) :: kT, mu_e, e_nk, dfde_nk, tau_nk, lw_nk, max_adiff, cpu, wall, gflops, abs_tol, rtmp
    1774                 :             :  logical :: send_data
    1775                 :             :  character(len=500) :: msg
    1776                 :             :  character(len=fnlen) :: path
    1777                 :           1 :  type(rta_t) :: ibte
    1778                 :             : !arrays
    1779                 :             :  integer :: units(2), dims(4)
    1780                 :           1 :  logical,allocatable :: converged(:)
    1781                 :             :  real(dp) :: vec3(3), sym_vec(3), mat33(3,3), f_kq(3), work33(3,3)
    1782                 :             :  real(dp) :: inv_sig_p(3,3)
    1783                 :           3 :  real(dp) :: fsum_eh(3,2,ebands%nsppol), max_adiff_spin(ebands%nsppol)
    1784                 :           2 :  real(dp) :: onsager(3,3,3,ebands%nsppol)
    1785                 :           1 :  real(dp),pointer :: sig_p(:,:,:,:), mob_p(:,:,:,:), sbk_p(:,:,:), kappa_p(:,:,:), pi_p(:,:,:)
    1786                 :           1 :  real(dp),target,allocatable :: ibte_sigma(:,:,:,:,:), ibte_mob(:,:,:,:,:), ibte_rho(:,:,:)
    1787                 :           1 :  real(dp),target,allocatable :: ibte_seebeck(:,:,:,:), ibte_kappa(:,:,:,:), ibte_pi(:,:,:,:)
    1788                 :           1 :  real(dp),allocatable :: grp_srate(:,:,:,:), fkn_in(:,:,:,:), fkn_out(:,:,:,:), fkn_efield(:,:,:,:), fkn_serta(:,:,:,:), taukn_serta(:,:,:,:)
    1789                 :             :  real(dp) :: fact_sbk
    1790                 :             :  character(len=2) :: components(3)
    1791                 :           1 :  real(dp), allocatable :: sig_gen(:,:,:,:), mob_gen(:,:,:,:), sig_l21(:,:,:,:), sig_l22(:,:,:,:), mob_21(:,:,:,:), mob_22(:,:,:,:)
    1792                 :             :  type :: scatk_t
    1793                 :             : 
    1794                 :             :    integer :: rank = xmpi_undefined_rank
    1795                 :             : 
    1796                 :             :    integer :: nq_ibzk_eff
    1797                 :             :    ! Number of effective q-points in the IBZ(k)
    1798                 :             : 
    1799                 :             :    integer :: lgk_nsym
    1800                 :             :    ! Number of symmetry operations in the little group of k.
    1801                 :             : 
    1802                 :             :    integer,allocatable :: lgk_sym2glob(:,:)
    1803                 :             :    ! lgk_sym2glob(2, lgk_nsym)
    1804                 :             :    ! Mapping isym_lg --> [isym, itime]
    1805                 :             :    ! where isym is the index of the operation in the global array **crystal%symrec**
    1806                 :             :    ! and itim is 2 if time-reversal T must be included else 1. Depends on ikcalc
    1807                 :             : 
    1808                 :             :    integer,allocatable :: kq_symtab(:,:)
    1809                 :             :    ! kq_symtab(6, nq_ibzk_eff)
    1810                 :             : 
    1811                 :             :    real(dp),allocatable :: vals(:,:,:,:)
    1812                 :             :    ! (nq_ibzk_eff, nbsum, nbcalc, ntemp)
    1813                 :             :  end type scatk_t
    1814                 :             : 
    1815                 :           1 :  type(scatk_t),target,allocatable :: sr(:,:)
    1816                 :             :  type(scatk_t),pointer :: sr_p
    1817                 :             : 
    1818                 :             : ! *************************************************************************
    1819                 :             : 
    1820                 :           1 :  my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm)
    1821         [ +  + ]:           3 :  units = [std_out, ab_out]
    1822                 :             : 
    1823                 :           1 :  call wrtout(units, ch10//' Entering IBTE driver.')
    1824                 :             :  call wrtout(units, sjoin("- Reading SERTA lifetimes and e-ph scattering operator from:", &
    1825                 :           1 :              dtfil%filsigephin), newlines=1, do_flush=.True.)
    1826                 :             : 
    1827                 :             :  ! Initialize IBTE object
    1828   [ -  +  -  +  :           1 :  ibte = rta_new(dtset, dtfil, ngfftc, cryst, ebands, pawtab, psps, comm)
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  -  
                      + ]
    1829                 :             : 
    1830                 :             :  ! Compute RTA transport quantities
    1831                 :           1 :  call ibte%compute_rta(cryst, dtset, dtfil, comm)
    1832                 :             : 
    1833                 :           1 :  nkcalc = ibte%nkcalc
    1834                 :           1 :  nkibz = ibte%ebands%nkpt; nsppol = ibte%nsppol; ntemp = ibte%ntemp
    1835                 :           1 :  bmin = ibte%bmin; bmax = ibte%bmax
    1836                 :             :  !call wrtout(std_out, sjoin(" nkcalc", itoa(nkcalc), "bmin:", itoa(bmin), "bmax:", itoa(bmax)))
    1837                 :             : 
    1838                 :             :  ! Get units conversion factor including spin degeneracy.
    1839                 :             : !max_occ = two / (self%nspinor * self%nsppol)
    1840                 :             : !fact_sigma = max_occ * (siemens_SI / Bohr_meter) / 100.  ! Siemens / cm
    1841                 :             : ! fact_mob   = fact_sigma * 100.**3 / e_Cb * Bohr_meter**3 ! cm^2 / V / s
    1842                 :           1 :  fact_sbk   = -volt_SI * kb_HaK                           ! Volt / Kelvin
    1843                 :             : !call wrtout(std_out,"factors: ")
    1844                 :             : ! write (std_out,*) fact_sigma,  fact_sbk
    1845                 :             : 
    1846                 :             :  !call ibte%read_scattering()
    1847                 :             :  ! Loops and memory are distributed over k-points and collinear spins
    1848   [ -  +  +  -  :          11 :  ABI_MALLOC(sr, (nkcalc, nsppol))
          -  +  +  -  +  
          -  +  -  -  +  
          -  +  -  +  +  
          +  +  +  +  -  
          -  +  -  +  -  
                      + ]
    1849                 :           1 :  cnt = 0
    1850         [ +  + ]:           2 :  do spin=1,nsppol
    1851         [ +  + ]:           8 :    do ikcalc=1,nkcalc
    1852                 :           6 :      cnt = cnt + 1
    1853                 :           7 :      sr(ikcalc, spin)%rank = mod(cnt, nprocs)
    1854                 :             :    end do
    1855                 :             :  end do
    1856                 :             : 
    1857                 :           1 :  call cwtime(cpu, wall, gflops, "start")
    1858                 :             :  ! Master reads and sends data to the rank treating (ikcalc, spin).
    1859         [ +  - ]:           1 :  if (my_rank == master) then
    1860         [ -  + ]:           1 :    NCF_CHECK(nctk_open_read(ncid, dtfil%filsigephin, xmpi_comm_self))
    1861                 :             :  end if
    1862                 :             : 
    1863         [ +  + ]:           2 :  do spin=1,nsppol
    1864         [ +  + ]:           8 :    do ikcalc=1,nkcalc
    1865                 :           6 :      sr_p => sr(ikcalc, spin)
    1866                 :           6 :      receiver = sr_p%rank
    1867                 :           6 :      send_data = master /= receiver
    1868         [ +  - ]:           6 :      if (.not. any(my_rank == [master, receiver])) cycle
    1869                 :             :      !call wrtout(std_out, sjoin(" Sending data from my_rank:", itoa(my_rank), " to:", itoa(receiver)))
    1870                 :             : 
    1871         [ +  - ]:           6 :      if (my_rank == master) then
    1872                 :             :        ! Get ncid of group used to store scattering rate for this k-point.
    1873                 :           6 :        ncerr = nf90_inq_ncid(ncid, strcat("srate_k", itoa(ikcalc), "_s", itoa(spin)), grp_ncid)
    1874         [ -  + ]:           6 :        if (ncerr /= NF90_NOERR) then
    1875                 :           0 :          ABI_ERROR("Cannot find collision terms in SIGEPH file. Rerun eph_task -4 step with ibte_prep 1.")
    1876                 :             :        end if
    1877         [ -  + ]:           6 :        NCF_CHECK(nctk_get_dim(grp_ncid, "nq_ibzk_eff", sr_p%nq_ibzk_eff))
    1878         [ -  + ]:           6 :        NCF_CHECK(nctk_get_dim(grp_ncid, "nbsum", nbsum))
    1879         [ -  + ]:           6 :        NCF_CHECK(nctk_get_dim(grp_ncid, "nbcalc", nbcalc))
    1880         [ -  + ]:           6 :        NCF_CHECK(nctk_get_dim(grp_ncid, "lgk_nsym", sr_p%lgk_nsym))
    1881         [ +  + ]:          30 :        dims = [sr_p%nq_ibzk_eff, nbsum, nbcalc, sr_p%lgk_nsym]
    1882                 :             :      end if
    1883                 :             : 
    1884         [ -  + ]:           6 :      if (send_data) then
    1885                 :           0 :        tag = size(dims)
    1886         [ #  # ]:           0 :        if (my_rank == master) call xmpi_send(dims, receiver, tag, comm, ierr)
    1887         [ #  # ]:           0 :        if (my_rank == receiver) then
    1888                 :           0 :          call xmpi_recv(dims, master, tag, comm, ierr)
    1889                 :           0 :          sr_p%nq_ibzk_eff = dims(1); nbsum = dims(2); nbcalc = dims(3); sr_p%lgk_nsym = dims(4)
    1890                 :             :        end if
    1891                 :             :      end if
    1892                 :             : 
    1893                 :             :      ! Note that the size along the (n, m) axis does not depend on the kcalc index.
    1894   [ -  +  +  -  :       18434 :      ABI_CALLOC(sr_p%vals, (sr_p%nq_ibzk_eff, bmin:bmax, bmin:bmax, ntemp))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  +  -  +  
          -  -  +  -  +  
          -  +  +  +  +  
             +  +  +  +  
                      + ]
    1895   [ -  +  +  -  :          18 :      ABI_MALLOC(sr_p%kq_symtab, (6, sr_p%nq_ibzk_eff))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    1896   [ -  +  +  -  :          18 :      ABI_MALLOC(sr_p%lgk_sym2glob, (2, sr_p%lgk_nsym))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    1897                 :             : 
    1898         [ +  - ]:           6 :      if (my_rank == master) then
    1899         [ -  + ]:           6 :        NCF_CHECK(nf90_get_var(grp_ncid, nctk_idname(grp_ncid, "kq_symtab"), sr_p%kq_symtab))
    1900         [ -  + ]:           6 :        NCF_CHECK(nf90_get_var(grp_ncid, nctk_idname(grp_ncid, "lgk_sym2glob"), sr_p%lgk_sym2glob))
    1901                 :             : 
    1902                 :             :        ! Note that on file, we have:
    1903                 :             :        !
    1904                 :             :        !      nctkarr_t("srate", "dp", "nq_ibzk_eff, nbsum, nbcalc, ntemp")
    1905                 :             :        !
    1906                 :             :        ! but in terms of n, m indices we have that the:
    1907                 :             :        !
    1908                 :             :        !   n index: bstart_ks bstop_ks
    1909                 :             :        !   m index: bsum_start up to bsum_stop to account for phonon emission/absorption.
    1910                 :             :        !
    1911                 :             :        ! so we have to insert the values in bmin:bmax slice.
    1912                 :             :        ! TODO: Recheck this part.
    1913   [ -  +  +  -  :          36 :        ABI_MALLOC(grp_srate, (sr_p%nq_ibzk_eff, nbsum, nbcalc, ntemp))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  +  -  +  
          -  -  +  -  +  
                   -  + ]
    1914         [ -  + ]:           6 :        NCF_CHECK(nf90_get_var(grp_ncid, nctk_idname(grp_ncid, "srate"), grp_srate))
    1915                 :           6 :        ii = ibte%bstart_ks(ikcalc, spin)
    1916                 :           6 :        jj = ibte%bstop_ks(ikcalc, spin)
    1917   [ +  +  +  +  :       18404 :        sr_p%vals(:, bmin:bmax, ii:jj, :) = grp_srate(:, 1:bmax-bmin+1, 1:nbcalc, :)
             +  +  +  + ]
    1918         [ +  - ]:           6 :        ABI_SFREE(grp_srate)
    1919                 :             :      end if
    1920                 :             : 
    1921         [ -  + ]:           6 :      if (send_data) then
    1922         [ #  # ]:           0 :        tag = size(sr_p%vals)
    1923         [ #  # ]:           0 :        if (my_rank == master) then
    1924                 :           0 :          tag = tag + 1; call xmpi_send(sr_p%vals, receiver, tag, comm, ierr)
    1925                 :           0 :          tag = tag + 1; call xmpi_send(sr_p%kq_symtab, receiver, tag, comm, ierr)
    1926                 :           0 :          tag = tag + 1; call xmpi_send(sr_p%lgk_sym2glob, receiver, tag, comm, ierr)
    1927                 :             :        end if
    1928         [ #  # ]:           0 :        if (my_rank == receiver) then
    1929                 :           0 :          tag = tag + 1; call xmpi_recv(sr_p%vals, master, tag, comm, ierr)
    1930                 :           0 :          tag = tag + 1; call xmpi_recv(sr_p%kq_symtab, master, tag, comm, ierr)
    1931                 :           0 :          tag = tag + 1; call xmpi_recv(sr_p%lgk_sym2glob, master, tag, comm, ierr)
    1932                 :             :        end if
    1933                 :             :      end if
    1934                 :             : 
    1935         [ -  - ]:           1 :      if (send_data .and. my_rank /= receiver) call free_sr_ks(ikcalc, spin)
    1936                 :             : 
    1937                 :             :    end do ! spin
    1938                 :             :  end do ! ikcalc
    1939                 :             : 
    1940         [ +  - ]:           1 :  if (my_rank == master) then
    1941         [ -  + ]:           1 :    NCF_CHECK(nf90_close(ncid))
    1942                 :             :  end if
    1943                 :             : 
    1944                 :           1 :  call cwtime_report(" sigeph IO", cpu, wall, gflops)
    1945                 :             : 
    1946                 :             :  ! Solve the linearized BTE with B = 0.
    1947                 :             :  !
    1948                 :             :  !   F_\nk = e df/de_\nk v_\nk \tau^0 + \tau^0 \sum_{mq} Srate_{nk,mq} F_{m,k+q}
    1949                 :             :  !
    1950                 :             :  ! where F is a vector in Cartesian coordinates and tau^0 is the SERTA relaxation time.
    1951                 :             :  !
    1952                 :             :  ! Take advantage of the following symmetry properties:
    1953                 :             :  !
    1954                 :             :  ! 1. F_k = F_Sk.
    1955                 :             :  ! 2. F_{-k} = -F_k if TR symmetry.
    1956                 :             :  ! 3. The q-space integration is reduced to the IBZ(k) using the symmetries of the little group of k.
    1957                 :             : 
    1958                 :             :  !call ibte%solve_ibte(solver_type=1)
    1959                 :             : 
    1960                 :           1 :  bsize = bmax - bmin + 1
    1961   [ -  +  +  -  :         587 :  ABI_CALLOC(fkn_in, (3, nkibz, bmin:bmax, nsppol))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
          +  +  +  +  +  
             +  +  +  + ]
    1962   [ -  +  +  -  :         586 :  ABI_CALLOC(fkn_out, (3, nkibz, bmin:bmax, nsppol))
          -  +  +  -  -  
          +  +  -  -  +  
          -  +  -  +  +  
          +  +  +  +  +  
                   +  + ]
    1963   [ -  +  +  -  :         586 :  ABI_CALLOC(fkn_serta, (3, nkibz, bmin:bmax, nsppol))
          -  +  +  -  -  
          +  +  -  -  +  
          -  +  +  +  +  
             +  +  +  +  
                      + ]
    1964   [ -  +  +  -  :         586 :  ABI_CALLOC(taukn_serta, (3, nkibz, bmin:bmax, nsppol))
          -  +  +  -  -  
          +  +  -  -  +  
          -  +  +  +  +  
             +  +  +  +  
                      + ]
    1965   [ -  +  +  -  :           4 :  ABI_MALLOC(ibte_sigma, (3, 3, 2, nsppol, ntemp))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    1966   [ -  +  +  -  :           4 :  ABI_MALLOC(ibte_seebeck, (3, 3, nsppol, ntemp))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    1967   [ -  +  +  -  :           3 :  ABI_MALLOC(ibte_pi, (3, 3, nsppol, ntemp))
          -  +  +  -  -  
             +  -  +  -  
                      + ]
    1968   [ -  +  +  -  :           3 :  ABI_MALLOC(ibte_mob, (3, 3, 2, nsppol, ntemp))
          -  +  +  -  -  
             +  -  +  -  
                      + ]
    1969   [ -  +  +  -  :           3 :  ABI_MALLOC(converged, (ntemp))
          +  -  +  -  -  
                +  -  + ]
    1970   [ -  +  +  -  :           3 :  ABI_MALLOC(sig_gen, (3, 3, 2, nsppol))
          +  -  +  -  -  
                +  -  + ]
    1971   [ -  +  +  -  :           2 :  ABI_MALLOC(sig_l21, (3, 3, 2, nsppol))
             -  +  -  + ]
    1972   [ -  +  +  -  :           2 :  ABI_MALLOC(sig_l22, (3, 3, 2, nsppol))
             -  +  -  + ]
    1973   [ -  +  +  -  :           2 :  ABI_MALLOC(mob_gen, (3, 3, 2, nsppol))
             -  +  -  + ]
    1974   [ -  +  +  -  :           2 :  ABI_MALLOC(mob_21, (3, 3, 2, nsppol))
             -  +  -  + ]
    1975   [ -  +  +  -  :           2 :  ABI_MALLOC(mob_22, (3, 3, 2, nsppol))
             -  +  -  + ]
    1976   [ -  +  +  -  :           3 :  ABI_MALLOC(ibte_kappa, (3, 3, nsppol, ntemp))
          -  +  +  -  -  
             +  -  +  -  
                      + ]
    1977                 :           1 :  abs_tol = dtset%ibte_abs_tol
    1978                 :             : 
    1979                 :             :  ! If the fermi level is inside the gap, F_k is gonna be very small
    1980                 :             :  ! hence once should use a much smaller tolerance to converge.
    1981                 :             :  ! According to numerical tests, a reasonable value of abs_tol can be estimated from the free carrier density using:
    1982                 :             :  !
    1983                 :             :  !  1e-20 * e_density (in cm**-3)
    1984                 :             :  !
    1985                 :             :  ! These are the numerical values used to derive the fit:
    1986                 :             : 
    1987                 :             :  !  max_adiff = np.array([9e-12, 5.6e-6, 2.7e-6, 8.2e-60, 2.9e-46, 6.9e-6, 2.9e-8, 9.5E+00, 7.3E-04, 9.2E-04, 8.4E-04])
    1988                 :             :  !  e_density = np.array([0.97e8, 0.86e13, 0.26e14, 0.1e-40, 0.89e-26, 0.45e14, 0.28e12, 0.10E+19, 0.12E+16, 0.10E+15, 0.90E+14])
    1989                 :             : 
    1990         [ -  + ]:           1 :  if (abs_tol <= zero) then
    1991   [ #  #  #  #  :           0 :    rtmp = minval(ibte%n_ehst, mask=ibte%n_ehst > zero) * ibte%nsppol
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    1992                 :           0 :    abs_tol = 1e-20 * rtmp / cryst%ucvol / Bohr_cm**3
    1993                 :           0 :    call wrtout(std_out, " Input ibte_abs_tol <= zero ==> computing abs tolerance from minimal carrier density over all T")
    1994                 :           0 :    call wrtout(std_out, " using: abs_tol = 1e-20 * e_density (in cm**-3)")
    1995                 :           0 :    call wrtout(std_out, sjoin(" abs_tol:", ftoa(abs_tol), " from carrier_density:", ftoa(rtmp / cryst%ucvol / Bohr_cm**3)))
    1996                 :             :  end if
    1997                 :             : 
    1998         [ +  - ]:           1 :  if (my_rank == master) then
    1999         [ +  - ]:           1 :    path = strcat(dtfil%filnam_ds(4), "_RTA.nc")
    2000                 :           1 :    call wrtout(units, ch10//sjoin("- Writing IBTE transport results to:", path))
    2001         [ -  + ]:           1 :    NCF_CHECK(nctk_open_modify(ncid, path , xmpi_comm_self))
    2002                 :             : 
    2003                 :             :    ncerr = nctk_def_dims(ncid, [ &
    2004                 :             :       nctkdim_t("nkibz", nkibz), nctkdim_t("bsize", bsize), nctkdim_t("nkcalc", ibte%nkcalc) &
    2005         [ +  + ]:           4 :    ], defmode=.True.)
    2006         [ -  + ]:           1 :    NCF_CHECK(ncerr)
    2007                 :             : 
    2008                 :             :    ncerr = nctk_def_arrays(ncid, [ &
    2009                 :             :      nctkarr_t('fkn_out_sigma', "dp", "three, nkibz, bsize, nsppol, ntemp"), &
    2010                 :             :      nctkarr_t('ibte_sigma', "dp", "three, three, two, nsppol, ntemp"), &
    2011                 :             :      nctkarr_t('ibte_mob', "dp", "three, three, two, nsppol, ntemp"), &
    2012                 :             :      nctkarr_t("kcalc2ibz", "int", "nkcalc, six"), &
    2013                 :             :      nctkarr_t("kcalc2ebands", "int", "six, nkcalc"), &
    2014                 :             :      nctkarr_t("kibz", "dp", "three, nkibz"), &
    2015                 :             :      nctkarr_t('ibte_rho', "dp", "three, three, ntemp") &
    2016         [ +  + ]:           8 :    ], defmode=.True.)
    2017         [ -  + ]:           1 :    NCF_CHECK(ncerr)
    2018                 :             : 
    2019         [ -  + ]:           1 :    NCF_CHECK(nctk_set_datamode(ncid))
    2020                 :             :  end if
    2021                 :             : 
    2022                 :           1 :  cnt = 0
    2023         [ +  + ]:           3 :  do itemp=1,ntemp
    2024                 :             :  !do itemp=ntemp, 1, -1
    2025                 :           2 :    cnt = cnt + 1
    2026                 :           2 :    kT = max(ibte%kTmesh(itemp), one * kb_HaK)
    2027                 :           2 :    mu_e = ibte%eph_mu_e(itemp)
    2028                 :           2 :    sig_p => ibte_sigma(:,:,:,:,itemp)
    2029                 :           2 :    mob_p => ibte_mob(:,:,:,:,itemp)
    2030                 :           2 :    sbk_p => ibte_seebeck(:,:,:,itemp)
    2031                 :           2 :    kappa_p => ibte_kappa(:,:,:,itemp)
    2032                 :           2 :    pi_p => ibte_pi(:,:,:,itemp)
    2033                 :             : 
    2034                 :           2 :    call wrtout(std_out," Value of kT: ", pre_newlines=1, newlines=1)
    2035                 :           2 :         write (std_out,*) kT
    2036                 :             : 
    2037                 :             : 
    2038                 :             :    ! Precompute tau_serta and fkn_serta for this T: f^'_nk v_\nk * \tau^0
    2039         [ +  + ]:           4 :    do spin=1,nsppol
    2040         [ +  + ]:          16 :      do ikcalc=1,nkcalc
    2041                 :             :        !ik_ibz = ibte%kcalc2ibz(ikcalc, 1)
    2042                 :          12 :        ik_ibz = ibte%kcalc2ebands(1, ikcalc)
    2043         [ +  + ]:          26 :        do band_k=ibte%bstart_ks(ikcalc, spin), ibte%bstop_ks(ikcalc, spin)
    2044                 :          12 :          lw_nk = ibte%linewidths(itemp, band_k, ik_ibz, spin, 1)  ! 1 --> SERTA linewidths.
    2045                 :          12 :          call safe_div(one, two * lw_nk, zero, tau_nk)
    2046         [ +  + ]:          48 :          taukn_serta(:, ik_ibz, band_k, spin) = tau_nk
    2047                 :          12 :          e_nk = ebands%eig(band_k, ik_ibz, spin)
    2048                 :          12 :          dfde_nk = occ_dfde(e_nk, kT, mu_e)
    2049         [ +  + ]:          60 :          fkn_serta(:, ik_ibz, band_k, spin) = tau_nk * dfde_nk * ibte%vbks(:, band_k, ik_ibz, spin)
    2050                 :             :        end do
    2051                 :             :      end do
    2052                 :             :    end do
    2053                 :             : 
    2054                 :             :    call wrtout(std_out, sjoin(" Begin IBTE loop for itemp:", itoa(itemp), ", KT:", ftoa(kT / kb_HaK), "[K]"), &
    2055                 :           2 :                pre_newlines=1, newlines=1)
    2056                 :             : 
    2057                 :             :    ! iter = 0 --> Compute SERTA transport tensors just for initial reference.
    2058   [ -  +  -  + ]:           2 :    call ibte_calc_tensors(ibte, cryst, itemp, kT, mu_e, fkn_serta, onsager, sig_p, mob_p, fsum_eh, comm, iet)
    2059                 :             : 
    2060                 :             :    !TODO fix dtset here ans use maxocc, CAREFUL, it has to be included in all L coeff. I think
    2061                 :             : !max_occ = two / (self%nspinor * self%nsppol)
    2062                 :             : ! fact_sigma = max_occ * (siemens_SI / Bohr_meter) / 100.  ! Siemens / cm
    2063                 :             : ! fact_mob   = fact_sigma * 100.**3 / e_Cb * Bohr_meter**3 ! cm^2 / V / s
    2064                 :             :  !fact_sbk   = volt_SI * kb_HaK                           ! Volt / Kelvin
    2065                 :             :   ! sig_p = fact_sigma * sig_p  ! siemens cm^-1
    2066                 :             :  !  mob_p = fact_mob   * mob_p  !
    2067                 :             : 
    2068                 :             :    ! Print mobility for semiconductors, conductivity for metals.
    2069         [ -  + ]:           2 :    if (ibte%assume_gap) then
    2070         [ #  # ]:           0 :      do spin=1,nsppol
    2071   [ #  #  #  #  :           0 :        mat33 = sum(mob_p(:,:,:,spin), dim=3)
                   #  # ]
    2072                 :             :        write(msg, "(i5,1x,es9.1, *(1x, f16.2))") &
    2073   [ #  #  #  # ]:           0 :          0, zero, mat33(1,1), mat33(2,2), mat33(3,3), sum(fsum_eh(:,:,spin))
    2074                 :             :      end do
    2075                 :             :    else
    2076         [ +  + ]:           4 :      do spin=1,nsppol
    2077   [ +  +  +  +  :          62 :        mat33 = sum(sig_p(:,:,:,spin), dim=3)
                   +  + ]
    2078                 :             :        write(msg, "(i5,1x,es9.1, *(1x, es16.6))") &
    2079   [ +  +  +  + ]:          20 :          0, zero, mat33(1,1), mat33(2,2), mat33(3,3), sum(fsum_eh(:,:,spin))
    2080                 :             :      end do
    2081                 :             :    end if
    2082                 :           2 :    call wrtout(std_out, msg)
    2083                 :             : 
    2084   [ +  -  +  -  :        1168 :    fkn_in = fkn_serta
          +  -  +  -  -  
          +  -  -  -  -  
          +  +  +  +  +  
                +  +  + ]
    2085                 :             :    ! TODO: B-field
    2086                 :             :    ! Initialize fkn_in either from SERTA or from previous T.
    2087                 :             :    !if (cnt == 1) fkn_in = fkn_serta
    2088                 :             :    !if (cnt > 1 ) fkn_in = fkn_out
    2089   [ +  +  +  +  :        1166 :    fkn_out = zero
             +  +  +  + ]
    2090                 :             : 
    2091                 :           2 :    max_et=2 !max_et =1 pour F^E et max_et=2 pour F^E et F^T, iet = 3 pour calculer kappa
    2092                 :             : 
    2093                 :             : ! start here with loop over E and T perturbations: once F^Eps is done, init F^T and converge it as well
    2094         [ +  + ]:           6 :    electherm_loop: do iet = 1, max_et
    2095                 :             : 
    2096         [ +  + ]:           4 :      if (iet == 2) then
    2097                 :             :      ! initialize F^T from F^E
    2098         [ +  + ]:           4 :        do spin=1,nsppol
    2099         [ +  + ]:          16 :           do ikcalc=1,nkcalc
    2100                 :          12 :             ik_ibz = ibte%kcalc2ebands(1, ikcalc)
    2101         [ +  + ]:          26 :             do band_k=ibte%bstart_ks(ikcalc, spin), ibte%bstop_ks(ikcalc, spin)
    2102                 :          12 :                e_nk = ebands%eig(band_k, ik_ibz, spin)
    2103                 :             :               !Which one of the following is correct ?
    2104                 :             :               ! fkn_in(:, ik_ibz, band_k, spin)  = fkn_serta(:, ik_ibz, band_k, spin) * (e_nk-mu_e)/kT
    2105                 :             :                !fkn_in(:, ik_ibz, band_k, spin)  = fkn_efield(:, ik_ibz, band_k, spin) * (e_nk-mu_e)/kT
    2106         [ +  + ]:          48 :                fkn_in(:, ik_ibz, band_k, spin)  = fkn_efield(:, ik_ibz, band_k, spin) * (e_nk-mu_e)
    2107         [ +  + ]:          60 :                fkn_serta(:, ik_ibz, band_k, spin)  = fkn_serta(:, ik_ibz, band_k, spin) * (e_nk-mu_e)
    2108                 :             :             end do !band_k
    2109                 :             :           end do !ikcalc
    2110                 :             :         end do !spin
    2111         [ -  + ]:           2 :        ABI_CHECK(converged(itemp), "Warning: E field BTE not converged, I will not try to converge the T gradient")
    2112         [ -  + ]:           2 :        if (.not. converged(itemp)) exit electherm_loop
    2113                 :             :      end if ! iet == 2  ?????
    2114                 :             : 
    2115                 :             : 
    2116                 :             :      ! Begin iterative solver.
    2117         [ +  - ]:          25 :      iter_loop: do iter=1,dtset%ibte_niter
    2118                 :             : 
    2119                 :             :        ! call wrtout(std_out," check beginning loop, iter, iet:", pre_newlines=1, newlines=1)
    2120                 :             :        ! write (std_out,*) iter, iet
    2121                 :             : 
    2122                 :             :         ! Loop over the nk index in F_nk.
    2123         [ +  + ]:          50 :        do spin=1,nsppol
    2124         [ +  + ]:         200 :           do ikcalc=1,nkcalc
    2125                 :         150 :             sr_p => sr(ikcalc, spin)
    2126         [ +  - ]:         150 :             if (sr_p%rank /= my_rank) cycle ! MPI parallelism
    2127                 :         150 :             ik_ibz = ibte%kcalc2ebands(1, ikcalc)
    2128         [ +  + ]:         325 :             do band_k=ibte%bstart_ks(ikcalc, spin), ibte%bstop_ks(ikcalc, spin)
    2129                 :             : 
    2130                 :             :               ! Summing over the q-points in the effective IBZ(k) and the m band index.
    2131                 :             :               ! Results stored in vec3. Integration weights are already included.
    2132                 :         150 :               vec3 = zero
    2133         [ +  + ]:         300 :               do band_sum=ibte%bmin, ibte%bmax
    2134         [ +  + ]:      229825 :                 do iq_sum=1, sr_p%nq_ibzk_eff
    2135                 :      229525 :                   ikq_ibz = sr_p%kq_symtab(1, iq_sum); isym_kq = sr_p%kq_symtab(2, iq_sum)
    2136                 :      229525 :                   trev_kq = sr_p%kq_symtab(6, iq_sum) !; g0_kq = sr_p%kq_symtab(3:5, iq_sum)
    2137                 :             :                   ! Build F_{m,k+q} in the effective IBZ(k) from fkn_in using symmetries (need k+q --> IBZ map)
    2138                 :             :                   ! Use transpose(R) because we are using the tables for the wavefunctions
    2139                 :             :                   ! In this case listkk has been called with symrec and use_symrec=False
    2140                 :             :                   ! so q_bz = S^T q_ibz where S is the isym_kq symmetry
    2141                 :             :                   ! vkq = matmul(transpose(cryst%symrel_cart(:,:,isym_kq)), vkq)
    2142   [ +  +  +  + ]:     2983825 :                   mat33 = transpose(cryst%symrel_cart(:,:,isym_kq))
    2143   [ +  +  +  + ]:     2983825 :                   f_kq = matmul(mat33, fkn_in(:, ikq_ibz, band_sum, spin))
    2144   [ -  +  -  - ]:      229525 :                   if (trev_kq == 1) f_kq = -f_kq
    2145         [ +  + ]:      918250 :                   vec3 = vec3 + sr_p%vals(iq_sum, band_sum, band_k, itemp) * f_kq(:)
    2146                 :             :                 end do ! iq_sum
    2147                 :             :               end do ! band_k
    2148                 :             : 
    2149                 :             :               ! Symmetrize intermediate results using the operations of the little group of k.
    2150                 :         150 :               sym_vec = zero
    2151         [ +  + ]:         800 :               do isym_lgk=1,sr_p%lgk_nsym
    2152                 :         650 :                 isym = sr_p%lgk_sym2glob(1, isym_lgk)
    2153                 :         650 :                 itime = sr_p%lgk_sym2glob(2, isym_lgk)
    2154   [ +  +  +  + ]:        8450 :                 mat33 = transpose(cryst%symrel_cart(:,:,isym))
    2155                 :             :                 !if(itime == 1) mat33 = -mat33 ! FIXME: here there's a different convention for TR used in m_lgroup
    2156   [ +  +  +  +  :        4550 :                 if (itime == 2) mat33 = -mat33
                   +  + ]
    2157   [ +  +  +  +  :       10550 :                 sym_vec = sym_vec + matmul(mat33, vec3)
                   +  + ]
    2158                 :             :               end do
    2159         [ +  + ]:         600 :               sym_vec = taukn_serta(:, ik_ibz, band_k, spin) * sym_vec / sr_p%lgk_nsym
    2160                 :             :               ! if iet 2 serta and fkn_in have been multiplied by e-mu / T
    2161         [ +  + ]:         750 :               fkn_out(:, ik_ibz, band_k, spin) = fkn_serta(:, ik_ibz, band_k, spin) + sym_vec
    2162                 :             :             end do ! band_k
    2163                 :             :           end do ! ikcalc
    2164                 :             :        end do ! spin
    2165                 :             : 
    2166                 :             : 
    2167                 :          25 :        call xmpi_sum(fkn_out, comm, ierr)
    2168                 :             : 
    2169                 :             :        ! Write fkn_out_sigma to disk.
    2170         [ +  - ]:          25 :        if (my_rank == master) then
    2171   [ +  +  -  +  :         150 :            NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "fkn_out_sigma"), fkn_out, start=[1,1,1,1,itemp]))
                   -  - ]
    2172                 :             :        end if
    2173                 :             : 
    2174         [ +  + ]:          50 :        do spin=1,nsppol
    2175   [ +  +  +  +  :       14575 :          max_adiff_spin(spin) = maxval(abs(fkn_out(:,:,:,spin) - fkn_in(:,:,:,spin)))
          +  +  +  +  +  
             -  -  +  -  
                      - ]
    2176                 :             :        end do
    2177   [ +  -  -  +  :          75 :        max_adiff = maxval(max_adiff_spin)
             -  -  +  + ]
    2178                 :             : 
    2179                 :             : 
    2180   [ +  -  -  +  :         725 :        mob_gen=sig_gen
          -  -  +  +  +  
             +  +  +  +  
                      + ]
    2181   [ +  -  -  +  :         725 :        mob_21=sig_gen
          -  -  +  +  +  
             +  +  +  +  
                      + ]
    2182   [ +  -  -  +  :         725 :        mob_22=sig_gen
          -  -  +  +  +  
             +  +  +  +  
                      + ]
    2183                 :             : 
    2184                 :             : !Here I test if F^T=(eps-mu)F^E
    2185                 :             : !        if (iet==2) then
    2186                 :             : !         do spin=1,nsppol
    2187                 :             : !          do ikcalc=1,nkcalc
    2188                 :             : !            ik_ibz = ibte%kcalc2ebands(1, ikcalc)
    2189                 :             : !            do band_k=ibte%bstart_ks(ikcalc, spin), ibte%bstop_ks(ikcalc, spin)
    2190                 :             : !               e_nk = ebands%eig(band_k, ik_ibz, spin)
    2191                 :             :               !Which one of the following is correct ?
    2192                 :             :               ! fkn_in(:, ik_ibz, band_k, spin)  = fkn_serta(:, ik_ibz, band_k, spin) * (e_nk-mu_e)/kT
    2193                 :             :                !fkn_in(:, ik_ibz, band_k, spin)  = fkn_efield(:, ik_ibz, band_k, spin) * (e_nk-mu_e)/kT
    2194                 :             : !               fkn_out(:, ik_ibz, band_k, spin)  = fkn_efield(:, ik_ibz, band_k, spin) * (e_nk-mu_e)
    2195                 :             :                !fkn_serta(:, ik_ibz, band_k, spin)  = fkn_serta(:, ik_ibz, band_k, spin) * (e_nk-mu_e)
    2196                 :             : !            end do
    2197                 :             : !          end do
    2198                 :             : !        end do
    2199                 :             : !       end if
    2200                 :             : 
    2201                 :             : 
    2202                 :             :        ! Compute transport tensors from fkn_out (= F_eps or F_T)
    2203   [ +  +  -  +  :          25 :        if(iet==1) call ibte_calc_tensors(ibte, cryst, itemp, kT, mu_e, fkn_out, onsager, sig_p, mob_p, fsum_eh, comm, iet)
                   -  + ]
    2204                 :             : ! call flush_unit(std_out)
    2205                 :             : 
    2206                 :             :       !For seebeck, use another array(sig_gen) because sig_p points towards ibte_sigma
    2207         [ +  + ]:          25 :       if(iet==2) call ibte_calc_tensors(ibte, cryst, itemp, kT, mu_e, fkn_out, onsager, sig_gen, mob_gen, fsum_eh, comm, iet)
    2208                 :             : 
    2209                 :             :        !check to find the bug
    2210                 :             : ! call wrtout(std_out," check 3", pre_newlines=1, newlines=1)
    2211                 :             : ! call flush_unit(std_out)
    2212                 :             : 
    2213                 :             :        ! Print mobility for semiconductors or conductivity for metals.
    2214         [ +  + ]:          25 :        if (iet==1) then! for F_eps and charge transport
    2215                 :             :          !sig_p = fact_sigma * sig_gen  ! siemens cm^-1
    2216                 :             :          !mob_p = fact_mob   * mob_gen  ! cm2/V/s
    2217                 :             : 
    2218                 :             : !call wrtout(std_out, "check 3bis: sig_gen, fact_sigma, sig_p")
    2219                 :             :  !               write(std_out,*) , sig_gen, fact_sigma, sig_p
    2220                 :             :           !check to find the bug
    2221                 :             : ! call wrtout(std_out," check 4", pre_newlines=1, newlines=1)
    2222                 :             : 
    2223         [ -  + ]:          23 :          if (ibte%assume_gap) then
    2224         [ #  # ]:           0 :            do spin=1,nsppol
    2225   [ #  #  #  #  :           0 :              mat33 = sum(mob_p(:,:,:,spin), dim=3)
                   #  # ]
    2226                 :             :              write(msg, "(i5,1x,es9.1,*(1x, f16.2))") &
    2227   [ #  #  #  # ]:           0 :                iter, max_adiff_spin(spin), mat33(1,1), mat33(2,2), mat33(3,3), sum(fsum_eh(:,:,spin))
    2228                 :             :            end do
    2229                 :             :          else
    2230         [ +  + ]:          46 :            do spin=1,nsppol
    2231   [ +  +  +  +  :         713 :              mat33 = sum(sig_p(:,:,:,spin), dim=3)
                   +  + ]
    2232                 :             :              write(msg, "(i5,1x,es9.1,*(1x, es16.6))") &
    2233   [ +  +  +  + ]:         230 :                iter, max_adiff_spin(spin), mat33(1,1), mat33(2,2), mat33(3,3), sum(fsum_eh(:,:,spin))
    2234                 :             :            end do
    2235                 :             :          end if
    2236                 :          23 :          call wrtout(std_out, msg)
    2237                 :             : 
    2238         [ +  - ]:           2 :        else if (iet == 2) then! for Seebeck, Seebeck=1/T sig_p^-1 * sig_gen
    2239                 :             :          ! output sig_p^-1 * sig_gen
    2240                 :             :          !pay attention when implementing if sigma=zero, bug ! impossible to get S.
    2241                 :             :          ! use matr3inv to inverse the matrix sigma but verify also that the det is not equal to zero !
    2242                 :             :          ! maybe type the command use "..." to be able to use the functions, check in the code
    2243                 :             : 
    2244                 :             :          !call wrtout(std_out, "check : sig_gen, sig_p")
    2245                 :             :          !write(std_out,*) sig_gen, sig_p
    2246                 :             : 
    2247                 :             :          !TODO: implement for inv_sig_p with two spins
    2248         [ +  + ]:           4 :          do spin=1,nsppol
    2249   [ +  -  +  +  :          62 :            call inv33(sum(sig_p(:,:,:,spin),dim=3), inv_sig_p)
          +  +  +  +  -  
                      + ]
    2250                 :             :            !We divide by 100 because sig_p is in Siemens cm^-1 and we want to retrieve meters
    2251                 :             :           ! work33 = matmul (inv_sig_p, sum(sig_gen(:,:,:,spin),dim=4))
    2252   [ +  +  +  +  :         164 :            mat33 = matmul (inv_sig_p, sum(sig_gen(:,:,:,spin),dim=3)) / (kT)
          +  +  +  +  +  
          +  +  +  +  -  
             +  +  +  + ]
    2253                 :             :           ! mat33 = (volt_SI / (ibte%kTmesh(itemp) / kb_HaK)) * matmul (inv_sig_p, sum(sig_gen(:,:,:,spin),dim=3))
    2254                 :             :            write(msg, "(i5,1x,es9.1,*(1x, es16.6))") &
    2255   [ +  +  +  + ]:          18 :                iter, max_adiff_spin(spin), mat33(1,1), mat33(2,2), mat33(3,3), sum(fsum_eh(:,:,spin))
    2256   [ +  +  +  + ]:          28 :            sbk_p (:,:,spin) = mat33
    2257                 :             :          end do
    2258                 :           2 :          call wrtout(std_out, msg)
    2259                 :             :        end if ! iet == 1, 2
    2260                 :             : 
    2261         [ -  + ]:          25 :        if (ibte%assume_gap) then
    2262                 :           0 :          write(msg, "(a5,1x,a9,*(1x, a16))")" ITER", "max_adiff", "mobility_e+h", "sum_k(df_k)"
    2263                 :             :        else
    2264                 :          25 :          write(msg, "(a5,1x,a9,*(1x, a16))")" ITER", "max_adiff", "conductivity", "sum_k(df_k)"
    2265                 :             :        end if
    2266                 :          25 :        call wrtout(std_out, msg)
    2267                 :             : 
    2268                 :             : 
    2269                 :             :        ! Check for convergence by testing max_k |F_k^i - F_k^{i-1}|.
    2270                 :          25 :        call wrtout (std_out, "Print check convergence: max_adiff, abs_tol")
    2271                 :          25 :        write(std_out,*) max_adiff, abs_tol
    2272                 :          25 :        converged(itemp) = max_adiff < abs_tol
    2273         [ +  + ]:          50 :        if (converged(itemp)) then
    2274                 :             :          call wrtout(std_out, sjoin(" IBTE solver converged after:", itoa(iter), &
    2275                 :           4 :                      "iterations within ibte_abs_tol:", ftoa(abs_tol)), pre_newlines=1)
    2276                 :             : 
    2277                 :           4 :          exit iter_loop
    2278                 :             :        else
    2279                 :             :          ! Linear mixing of fkn_in and fkn_out.
    2280   [ -  +  +  +  :       12264 :          fkn_in = (one - dtset%ibte_alpha_mix) * fkn_in + dtset%ibte_alpha_mix * fkn_out
          +  +  +  +  +  
                      + ]
    2281   [ +  +  +  +  :       12243 :          fkn_out = zero
             +  +  +  + ]
    2282                 :             :        end if
    2283                 :             :         !check where is the problem with iter loop
    2284                 :             : 
    2285                 :             :         !call wrtout(std_out," check iet:", pre_newlines=1, newlines=1)
    2286                 :             :         !write (std_out,*) iet
    2287                 :             : 
    2288                 :             :      end do iter_loop
    2289                 :             : 
    2290         [ -  + ]:           4 :      if (.not. converged(itemp)) then
    2291         [ #  # ]:           0 :        msg = sjoin("Not converged after:", itoa(dtset%ibte_niter), "max iterations")
    2292                 :           0 :        call wrtout(ab_out, msg, pre_newlines=1, newlines=1)
    2293                 :           0 :        ABI_WARNING(msg)
    2294                 :             :      end if
    2295                 :             : 
    2296                 :             :      !Change of unit here because sig_p is used in to calculate sbk in SI units
    2297   [ +  +  +  +  :        1174 :         if (iet == 1) fkn_efield = fkn_out
          +  -  +  -  +  
          -  -  +  +  -  
          +  -  +  -  +  
          -  +  -  +  +  
          +  +  +  +  +  
                      + ]
    2298         [ +  + ]:           6 :         if (iet==2) then
    2299                 :             :                 !iet =3
    2300                 :           2 :                 call ibte_calc_tensors(ibte, cryst, itemp, kT, mu_e, fkn_efield, onsager, sig_l21, mob_21, fsum_eh, comm, 3)
    2301                 :           2 :                 call ibte_calc_tensors(ibte, cryst, itemp, kT, mu_e, fkn_out, onsager, sig_l22, mob_22, fsum_eh, comm, 3)
    2302         [ +  + ]:           4 :                 do spin=1, nsppol
    2303   [ +  -  +  +  :          62 :                 call inv33(sum(sig_p(:,:,:,spin),dim=3), inv_sig_p)
          +  +  +  +  -  
                      + ]
    2304   [ +  +  +  +  :         252 :                 kappa_p(:,:,spin)=(1/kT)*(sum(sig_l22(:,:,:,spin), dim=3)-matmul(sum(sig_l21(:,:,:,spin),dim=3),sbk_p(:,:,spin)*kT))
          +  +  +  +  +  
          +  +  -  -  +  
          +  -  +  -  +  
          -  -  +  -  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  -  +  -  +  
          +  +  +  +  +  
                   +  - ]
    2305   [ +  +  +  +  :         166 :                 pi_p(:,:,spin)= matmul (sum(sig_l21(:,:,:,spin),dim=3), inv_sig_p) ! PI=L21/L11 in IBTE
          +  +  +  +  +  
          +  +  +  +  +  
             +  +  +  - ]
    2306                 :             :                 end do
    2307                 :             :         end if
    2308                 :             :    end do electherm_loop
    2309                 :             : ! end E/T loop
    2310                 :             : 
    2311                 :             : !Units conversion for sigma, at this step in order to keep atomic units for the calculation of S
    2312                 :             : !Truncated in purpose for nspinor=2 and nsppol=1 compared to how its done in the calc_tensor routine because dont have access to self in this routine
    2313   [ +  +  +  +  :          57 : sig_p=sig_p*(siemens_SI / Bohr_meter / cryst%ucvol) / 100
             +  +  +  + ]
    2314                 :             : !check if sig_p and sbk_p are empty
    2315                 :             : !call wrtout(std_out, "sig_p, sbk_p")
    2316                 :             : !write(std_out,*)  sig_p, sbk_p
    2317                 :             : 
    2318                 :             :  end do ! itemp
    2319                 :             : 
    2320                 :             :  !TODO: do it for spins as well
    2321   [ -  +  +  -  :           3 :  ABI_MALLOC(ibte_rho, (3, 3, ntemp))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
    2322         [ +  + ]:           3 :  do itemp=1,ntemp
    2323   [ +  +  +  +  :          62 :    work33 = sum(ibte_sigma(:,:,:,1,itemp), dim=3)
                   +  + ]
    2324   [ -  +  -  -  :           2 :    if (ibte%nsppol == 2) work33 = work33 + sum(ibte_sigma(:,:,:,2,itemp), dim=3)
             -  -  -  - ]
    2325                 :           2 :    call inv33(work33, mat33)
    2326   [ +  +  +  + ]:          27 :    ibte_rho(:, :, itemp) = 1e+6_dp * mat33
    2327                 :             :  end do
    2328                 :             : 
    2329                 :             : !ibte_sigma rho and seebeck seem empty, let's check
    2330                 :             : 
    2331                 :             : 
    2332                 :             : !write(*,*) "sigma: ", ibte_sigma
    2333                 :             : !write(*,*) "rho: ", ibte_rho
    2334                 :             : !write(*,*) "seebeck: ", ibte_seebeck
    2335                 :             : 
    2336                 :             : 
    2337         [ +  - ]:           1 :  if (my_rank == master) then
    2338                 :             :    ! Write final results to main output.
    2339         [ +  + ]:           4 :    components = ["xx", "yy", "zz"]
    2340         [ -  + ]:           1 :    if (ibte%assume_gap) then
    2341                 :             :      ! SemiConductor
    2342         [ #  # ]:           0 :      do ii=1,3
    2343                 :           0 :        call wrtout(units, sjoin(" Cartesian component of IBTE mobility tensor:", components(ii)))
    2344                 :           0 :        write(msg, "(a16,2(a32),a16)") 'Temperature [K]', 'e/h density [cm^-3]', 'e/h mobility [cm^2/Vs]', "Converged"
    2345                 :           0 :        call wrtout(units, msg)
    2346                 :             : 
    2347         [ #  # ]:           0 :        do spin=1,ibte%nsppol
    2348         [ #  # ]:           0 :          if (ibte%nsppol == 2) call wrtout(units, sjoin(" For spin:", stoa(spin)), newlines=1)
    2349                 :             : 
    2350         [ #  # ]:           0 :          do itemp=1,ibte%ntemp
    2351                 :             :            write(msg,"(f16.2,2e16.2,2f16.2,a16)") &
    2352                 :           0 :              ibte%kTmesh(itemp) / kb_HaK, &
    2353                 :           0 :              ibte%n_ehst(1, spin, itemp) / cryst%ucvol / Bohr_cm **3, &
    2354                 :           0 :              ibte%n_ehst(2, spin, itemp) / cryst%ucvol / Bohr_cm **3, &
    2355                 :           0 :              ibte_mob(ii, ii, 1, spin, itemp), ibte_mob(ii, ii, 2, spin, itemp), &
    2356                 :           0 :              yesno(converged(itemp))
    2357                 :           0 :            call wrtout(units, msg)
    2358                 :             :          end do ! itemp
    2359                 :             :        end do ! spin
    2360                 :             :        ! TODO:HERE look into adding seebeck output for semiconductors as well, check what happens with e and h components in tensors
    2361                 :             :        ! routine
    2362                 :           0 :        call wrtout(units, ch10)
    2363                 :             :      end do ! ii
    2364                 :             : 
    2365                 :             :    else
    2366                 :             :      ! Metals. Print conductivity (spin resolved) and resistivity (no spin resolved)
    2367         [ +  + ]:           3 :      do ii=1,2
    2368         [ +  + ]:           2 :        if (ii == 1) msg = " Conductivity [Siemens cm^-1] using IBTE"
    2369         [ +  + ]:           2 :        if (ii == 2) msg = " Resistivity [micro-Ohm cm] using IBTE"
    2370                 :           2 :        call wrtout(units, msg)
    2371                 :             : 
    2372         [ +  + ]:           2 :        nsp = ibte%nsppol; if (ii == 2) nsp = 1
    2373         [ +  + ]:           4 :        do spin=1,nsp
    2374         [ -  + ]:           2 :          if (ibte%nsppol == 2) call wrtout(units, sjoin(" For spin:", stoa(spin)), newlines=1)
    2375                 :           2 :          write(msg, "(5a16)") 'Temperature (K)', 'xx', 'yy', 'zz', "Converged"
    2376                 :           2 :          call wrtout(units, msg)
    2377         [ +  + ]:           8 :          do itemp=1,ibte%ntemp
    2378         [ +  + ]:           4 :            if (ii == 1) then
    2379   [ +  +  +  +  :          62 :              mat33 = sum(ibte_sigma(:,:,:,spin,itemp), dim=3)
                   +  + ]
    2380                 :             :            else
    2381   [ +  +  +  + ]:          26 :              mat33 = ibte_rho(:,:,itemp)
    2382                 :             :            end if
    2383                 :             :            write(msg,"(f16.2,3e16.6,a16)") &
    2384                 :           4 :              ibte%kTmesh(itemp) / kb_HaK, mat33(1,1), mat33(2,2), mat33(3,3), yesno(converged(itemp))
    2385                 :           6 :            call wrtout(units, msg)
    2386                 :             :          end do ! itemp
    2387                 :             :        end do ! spin
    2388                 :           3 :        call wrtout(units, ch10)
    2389                 :             :      end do ! ii
    2390                 :             : 
    2391                 :             :      ! HERE add output of Seebeck and kappa_el coefficients
    2392                 :             :      ! TODO: add off diagonal Seebeck and sigma coefficients
    2393                 :           1 :      msg = " Seebeck [Volts / Kelvin] using IBTE"
    2394                 :           1 :      call wrtout(units, msg)
    2395         [ +  + ]:           2 :      do spin=1,ibte%nsppol
    2396         [ -  + ]:           1 :        if (ibte%nsppol == 2) call wrtout(units, sjoin(" For spin:", stoa(spin)), newlines=1)
    2397                 :           1 :        write(msg, "(5a16)") 'Temperature (K)', 'xx', 'yy', 'zz', "Converged"
    2398                 :           1 :        call wrtout(units, msg)
    2399         [ +  + ]:           4 :        do itemp=1,ibte%ntemp
    2400   [ +  +  +  + ]:          26 :          mat33 = fact_sbk * ibte_seebeck(:,:,spin,itemp)
    2401                 :             :          write(msg,"(f16.2,3e16.6,a16)") &
    2402                 :           2 :            ibte%kTmesh(itemp) / kb_HaK, mat33(1,1), mat33(2,2), mat33(3,3), yesno(converged(itemp))
    2403                 :           3 :          call wrtout(units, msg)
    2404                 :             :        end do ! itemp
    2405                 :             :      end do ! spin
    2406                 :           1 :      call wrtout(units, ch10)
    2407                 :             : 
    2408                 :             : 
    2409                 :           1 :      msg = " Kappa [W/m*K] using IBTE"
    2410                 :           1 :      call wrtout(units, msg)
    2411         [ +  + ]:           2 :      do spin=1,ibte%nsppol
    2412         [ -  + ]:           1 :        if (ibte%nsppol == 2) call wrtout(units, sjoin(" For spin:", stoa(spin)), newlines=1)
    2413                 :           1 :        write(msg, "(5a16)") 'Temperature (K)', 'xx', 'yy', 'zz', "Converged"
    2414                 :           1 :        call wrtout(units, msg)
    2415         [ +  + ]:           4 :        do itemp=1,ibte%ntemp
    2416   [ +  +  +  + ]:          26 :          mat33 = volt_SI**2 * kb_HaK * (siemens_SI / Bohr_meter / cryst%ucvol)* ibte_kappa(:,:,spin,itemp)
    2417                 :             :          write(msg,"(f16.2,3e16.6,a16)") &
    2418                 :           2 :            ibte%kTmesh(itemp) / kb_HaK, mat33(1,1), mat33(2,2), mat33(3,3), yesno(converged(itemp))
    2419                 :           3 :          call wrtout(units, msg)
    2420                 :             :        end do ! itemp
    2421                 :             :      end do ! spin
    2422                 :           1 :      call wrtout(units, ch10)
    2423                 :             : 
    2424                 :           1 :      msg = " Peltier [Volts] using IBTE"
    2425                 :           1 :      call wrtout(units, msg)
    2426         [ +  + ]:           2 :      do spin=1,ibte%nsppol
    2427         [ -  + ]:           1 :        if (ibte%nsppol == 2) call wrtout(units, sjoin(" For spin:", stoa(spin)), newlines=1)
    2428                 :           1 :        write(msg, "(5a16)") 'Temperature (K)', 'xx', 'yy', 'zz', "Converged"
    2429                 :           1 :        call wrtout(units, msg)
    2430         [ +  + ]:           4 :        do itemp=1,ibte%ntemp
    2431   [ +  +  +  + ]:          26 :          mat33 = -volt_SI * ibte_pi(:,:,spin,itemp)
    2432                 :             :          write(msg,"(f16.2,3e16.6,a16)") &
    2433                 :           2 :            ibte%kTmesh(itemp) / kb_HaK, mat33(1,1), mat33(2,2), mat33(3,3), yesno(converged(itemp))
    2434                 :           3 :          call wrtout(units, msg)
    2435                 :             :        end do ! itemp
    2436                 :             :      end do ! spin
    2437                 :           1 :      call wrtout(units, ch10)
    2438                 :             : 
    2439                 :           1 :      msg = "Carrier density: "
    2440                 :           1 :      call wrtout(units, msg)
    2441                 :           1 :        write(msg, "(a16,a16,a32)") 'Temperature [K]', ' chem pot [eV]  ', 'e/h density [cm^-3]'
    2442                 :           1 :        call wrtout(units, msg)
    2443                 :             : 
    2444         [ +  + ]:           2 :        do spin=1,ibte%nsppol
    2445         [ -  + ]:           1 :          if (ibte%nsppol == 2) call wrtout(units, sjoin(" For spin:", stoa(spin)), newlines=1)
    2446                 :             : 
    2447         [ +  + ]:           4 :          do itemp=1,ibte%ntemp
    2448                 :             :            write(msg,"(f16.2,3e16.2)") &
    2449                 :           2 :              ibte%kTmesh(itemp) / kb_HaK, &
    2450                 :           2 :              ibte%eph_mu_e(itemp) * eV_Ha, &
    2451                 :           2 :              ibte%n_ehst(1, spin, itemp) / cryst%ucvol / Bohr_cm **3, &
    2452                 :           4 :              ibte%n_ehst(2, spin, itemp) / cryst%ucvol / Bohr_cm **3
    2453                 :           3 :            call wrtout(units, msg)
    2454                 :             :          end do ! itemp
    2455                 :             :        end do ! spin
    2456                 :           1 :        call wrtout(units, ch10)
    2457                 :             : 
    2458                 :             : 
    2459                 :             : 
    2460                 :             : 
    2461                 :             :    end if
    2462                 :             : 
    2463                 :             :    !pre = "_IBTE"
    2464                 :             :    !call ibte%write_tensor(dtset, irta, "sigma", ibte%sigma(:,:,:,:,:,irta), strcat(dtfil%filnam_ds(4), pre, "_SIGMA"))
    2465                 :             :    !call ibte%write_tensor(dtset, irta, "seebeck", ibte%seebeck(:,:,:,:,:,irta), strcat(dtfil%filnam_ds(4), pre, "_SBK"))
    2466                 :             :    !call ibte%write_tensor(dtset, irta, "kappa", ibte%kappa(:,:,:,:,:,irta), strcat(dtfil%filnam_ds(4), pre, "_KAPPA"))
    2467                 :             :    !call ibte%write_tensor(dtset, irta, "zte", ibte%zte(:,:,:,:,:,irta), strcat(dtfil%filnam_ds(4), pre, "_ZTE"))
    2468                 :             :    !call ibte%write_tensor(dtset, irta, "pi", ibte%pi(:,:,:,:,:,irta), strcat(dtfil%filnam_ds(4), pre, "_PI"))
    2469                 :             : 
    2470                 :             :    ! Print IBTE results to stdout and other external txt files (for the test suite)
    2471                 :             :    !call ibte%print_rta_txt_files(cryst, dtset, dtfil)
    2472                 :             :    ! Creates the netcdf file used to store the results of the calculation.
    2473         [ +  - ]:           1 :    path = strcat(dtfil%filnam_ds(4), "_RTA.nc")
    2474                 :           1 :    call wrtout(units, ch10//sjoin("- Writing IBTE transport results to:", path))
    2475                 :             :    !NCF_CHECK(nctk_open_modify(ncid, path , xmpi_comm_self))
    2476                 :             : 
    2477                 :             :    ncerr = nctk_def_arrays(ncid, [ &
    2478                 :             :      nctkarr_t('ibte_sigma', "dp", "three, three, two, nsppol, ntemp"), &
    2479                 :             :      nctkarr_t('ibte_mob', "dp", "three, three, two, nsppol, ntemp"), &
    2480                 :             :      nctkarr_t('ibte_rho', "dp", "three, three, ntemp"), &
    2481                 :             :      nctkarr_t('ibte_kappa', "dp", "three, three, nsppol, ntemp"), &
    2482                 :             :      nctkarr_t('ibte_seebeck', "dp", "three, three, nsppol, ntemp"), &
    2483                 :             :      nctkarr_t('ibte_pi', "dp", "three, three, nsppol, ntemp") &
    2484         [ +  + ]:           7 :    ], defmode=.True.)
    2485         [ -  + ]:           1 :    NCF_CHECK(ncerr)
    2486                 :             : 
    2487                 :             :    ! Write data.
    2488         [ -  + ]:           1 :    NCF_CHECK(nctk_set_datamode(ncid))
    2489         [ -  + ]:           1 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "ibte_sigma"), ibte_sigma))
    2490         [ -  + ]:           1 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "ibte_mob"), ibte_mob))
    2491         [ -  + ]:           1 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "ibte_rho"), ibte_rho))
    2492         [ -  + ]:           1 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "ibte_seebeck"), ibte_seebeck))
    2493         [ -  + ]:           1 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "ibte_pi"), ibte_pi))
    2494         [ -  + ]:           1 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "ibte_kappa"), ibte_kappa))
    2495         [ -  + ]:           1 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "kcalc2ibz"), ibte%kcalc2ibz))
    2496         [ -  + ]:           1 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "kcalc2ebands"), ibte%kcalc2ebands))
    2497         [ -  + ]:           1 :    NCF_CHECK(nf90_put_var(ncid, nctk_idname(ncid, "kibz"), ibte%ebands%kptns))
    2498         [ -  + ]:           1 :    NCF_CHECK(nf90_close(ncid))
    2499                 :             :  end if ! master
    2500                 :             : 
    2501                 :             :  ! Free memory
    2502         [ -  + ]:           1 :  ABI_FREE(fkn_serta)
    2503         [ -  + ]:           1 :  ABI_FREE(taukn_serta)
    2504         [ -  + ]:           1 :  ABI_FREE(fkn_in)
    2505         [ -  + ]:           1 :  ABI_FREE(fkn_out)
    2506         [ -  + ]:           1 :  ABI_FREE(ibte_sigma)
    2507         [ -  + ]:           1 :  ABI_FREE(ibte_seebeck)
    2508         [ -  + ]:           1 :  ABI_FREE(ibte_pi)
    2509         [ -  + ]:           1 :  ABI_FREE(ibte_mob)
    2510         [ -  + ]:           1 :  ABI_FREE(ibte_rho)
    2511         [ -  + ]:           1 :  ABI_FREE(ibte_kappa)
    2512         [ -  + ]:           1 :  ABI_FREE(converged)
    2513         [ -  + ]:           1 :  ABI_FREE(sig_gen)
    2514         [ -  + ]:           1 :  ABI_FREE(sig_l21)
    2515         [ -  + ]:           1 :  ABI_FREE(sig_l22)
    2516         [ -  + ]:           1 :  ABI_FREE(mob_gen)
    2517         [ -  + ]:           1 :  ABI_FREE(mob_21)
    2518         [ -  + ]:           1 :  ABI_FREE(mob_22)
    2519                 :             : 
    2520         [ +  + ]:           2 :  do spin=1,nsppol
    2521         [ +  + ]:           8 :    do ikcalc=1,nkcalc
    2522                 :           7 :      call free_sr_ks(ikcalc, spin)
    2523                 :             :    end do
    2524                 :             :  end do
    2525   [ +  -  +  +  :           7 :  ABI_FREE(sr)
          -  +  -  +  -  
                +  -  + ]
    2526                 :             : 
    2527   [ -  +  -  +  :           4 :  call ibte%free()
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
          +  +  -  -  +  
          -  -  -  -  -  
                -  -  - ]
    2528                 :             : 
    2529                 :             : contains
    2530                 :             : 
    2531                 :           6 : subroutine free_sr_ks(ikc, isp)
    2532                 :             :   integer,intent(in) :: ikc, isp
    2533         [ +  - ]:           6 :   ABI_SFREE(sr(ikc, isp)%vals)
    2534         [ +  - ]:           6 :   ABI_SFREE(sr(ikc, isp)%lgk_sym2glob)
    2535         [ +  - ]:           6 :   ABI_SFREE(sr(ikc, isp)%kq_symtab)
    2536                 :           6 : end subroutine free_sr_ks
    2537                 :             : 
    2538                 :             : end subroutine ibte_driver
    2539                 :             : !!***
    2540                 :             : 
    2541                 :             : !----------------------------------------------------------------------
    2542                 :             : 
    2543                 :             : !!****f* m_rta/ibte_calc_tensors
    2544                 :             : !! NAME
    2545                 :             : !! ibte_calc_tensors
    2546                 :             : !!
    2547                 :             : !! FUNCTION
    2548                 :             : !!   calculate transport tensors within iBTE method, from v x F expressions for current and sigma etc
    2549                 :             : !!   this routine now stays in atomic units to accommodate calculation of sigma and seebeck
    2550                 :             : !!
    2551                 :             : !! INPUTS
    2552                 :             : !! cryst<crystal_t>=Crystalline structure
    2553                 :             : !! comm=MPI communicator.
    2554                 :             : !!
    2555                 :             : !! SOURCE
    2556                 :             : 
    2557                 :          31 : subroutine ibte_calc_tensors(self, cryst, itemp, kT, mu_e, fk, onsager, sigma_eh, mob_eh, fsum_eh, comm, iet)
    2558                 :             : 
    2559                 :             : !Arguments ------------------------------------
    2560                 :             :  class(rta_t),intent(inout) :: self
    2561                 :             :  type(crystal_t),intent(in) :: cryst
    2562                 :             :  integer,intent(in) :: itemp
    2563                 :             :  real(dp),intent(in) :: kT, mu_e
    2564                 :             :  real(dp),intent(in) :: fk(3, self%ebands%nkpt, self%bmin:self%bmax, self%nsppol)
    2565                 :             :  real(dp),intent(out) :: sigma_eh(3,3,2,self%nsppol), mob_eh(3,3,2,self%nsppol)
    2566                 :             :  real(dp),intent(out) :: fsum_eh(3,2,self%nsppol), onsager(3,3,3,self%nsppol)
    2567                 :             :  integer,intent(in) :: comm, iet !iet to know which tensor we calculate, 1 for L11, 2 for L12 and 3 for L21 and L22
    2568                 :             : 
    2569                 :             : !Local variables ------------------------------
    2570                 :             : !scalars
    2571                 :             :  integer :: nsppol, nkibz, ib, ik_ibz, spin, ii, jj, ieh, cnt, nprocs, ia, time_opt
    2572                 :             :  real(dp) :: eig_nk, max_occ, wtk, emu_alpha, fact, fact0
    2573                 :             :  !real(dp) :: fact_sigma, fact_mob
    2574                 :             :  !arrays
    2575                 :             :  real(dp) :: vr(3), vv_tens(3,3)
    2576                 :             : !************************************************************************
    2577                 :             : 
    2578                 :             :  ABI_UNUSED(kt)
    2579                 :             : 
    2580                 :          31 :  nprocs = xmpi_comm_size(comm)
    2581                 :             : 
    2582                 :             :  ! Copy important dimensions
    2583                 :          31 :  nkibz = self%ebands%nkpt; nsppol = self%ebands%nsppol
    2584                 :          31 :  time_opt = 0 ! This to preserve the previous behaviour in which TR was not used.
    2585                 :             : 
    2586                 :             :  ! sigma_IBTE = (-S e^ / omega sum_\nk) (v_\nk \otimes F_\nk)
    2587                 :             :  ! with S the spin degeneracy factor.
    2588   [ +  +  +  +  :        2387 :  sigma_eh = zero; fsum_eh = zero; onsager = zero
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
                +  +  + ]
    2589                 :             : 
    2590                 :             :  ! Compute mobility_mu i.e. results in which lifetimes have been computed in a consistent way
    2591                 :             :  ! with the same the Fermi level. In all the other cases, indeed, we assume that tau does not depend on ef.
    2592                 :             :  !
    2593                 :             : 
    2594                 :             :  !TODO: rewrite this because every L (onsager coeff) is given with a minus sign and it's just the case for L11 and L22 normally
    2595                 :             :  ! Fortunately these minus signs compensate each other in the code or are suppressed by putting a -1 factor in front of sbk and PI
    2596                 :             :  ! It is not because of the sign of e !
    2597                 :             :  cnt = 0
    2598         [ +  + ]:          62 :  do spin=1,nsppol
    2599         [ +  + ]:        4557 :    do ik_ibz=1,nkibz
    2600                 :             :      !cnt = cnt + 1; if (mod(cnt, nprocs) /= my_rank) cycle ! MPI parallelism.
    2601                 :        4495 :      wtk = self%ebands%wtk(ik_ibz)
    2602                 :             : 
    2603         [ +  + ]:        9021 :      do ib=self%bmin,self%bmax
    2604                 :        4495 :        eig_nk = self%ebands%eig(ib, ik_ibz, spin)
    2605                 :             : 
    2606                 :             :        ! Compute outer product in vv_tens and symmetrize tensor.
    2607         [ +  + ]:       17980 :        vr(:) = self%vbks(:, ib, ik_ibz, spin)
    2608         [ +  + ]:       22475 :        do ia=1,3
    2609         [ +  + ]:       13485 :          if (ia == 1) then
    2610                 :             :            emu_alpha = one
    2611                 :             :          else
    2612                 :        8990 :            emu_alpha = (eig_nk - mu_e) ** (ia - 1)
    2613                 :             :          end if
    2614                 :             : 
    2615         [ +  + ]:       53940 :          do ii=1,3
    2616         [ +  + ]:      175305 :            do jj=1,3
    2617                 :      161820 :              vv_tens(ii, jj) = vr(ii) * fk(jj, ik_ibz, ib, spin)
    2618                 :             :            end do
    2619                 :             :          end do
    2620   [ +  +  +  + ]:      175305 :          vv_tens = vv_tens * emu_alpha
    2621   [ +  +  +  + ]:      175305 :          vv_tens = cryst%symmetrize_cart_tens33(vv_tens, time_opt)
    2622                 :             :         ! TODO: write the expression below in another way, without the useless sigma_eh - and without the sign - (adapt the
    2623                 :             :         ! calculations of coefficients in the main routine then)
    2624   [ +  +  +  + ]:       13485 :          if (ia == 1 .and. iet /= 3) then
    2625         [ +  + ]:        3770 :            ieh = 2; if (eig_nk >= mu_e) ieh = 1
    2626   [ +  +  +  + ]:       49010 :            sigma_eh(:,:,ieh,spin) = sigma_eh(:,:,ieh,spin) - wtk * vv_tens
    2627         [ +  + ]:       15080 :            fsum_eh(:,ieh,spin) = fsum_eh(:,ieh,spin) + wtk * cryst%symmetrize_cart_vec3(fk(:, ik_ibz, ib, spin), time_opt)
    2628                 :             : 
    2629                 :             :          !Here the tensorial product in order to get L21 and L22 to calculate kappa
    2630   [ +  +  +  + ]:        9715 :          else if (ia==2 .and. iet==3) then
    2631         [ +  + ]:         725 :                  ieh = 2; if (eig_nk >= mu_e) ieh = 1
    2632   [ +  +  +  + ]:        9425 :                  sigma_eh(:,:,ieh,spin) = sigma_eh(:,:,ieh,spin) - wtk * vv_tens
    2633         [ +  + ]:        2900 :            fsum_eh(:,ieh,spin) = fsum_eh(:,ieh,spin) + wtk * cryst%symmetrize_cart_vec3(fk(:, ik_ibz, ib, spin), time_opt)
    2634                 :             :          end if
    2635                 :             : 
    2636                 :             : 
    2637                 :             : 
    2638   [ +  +  +  + ]:      179800 :          onsager(:,:,ia,spin) = onsager(:,:,ia,spin) - wtk * vv_tens
    2639                 :             :        end do ! ia
    2640                 :             : 
    2641                 :             :      end do ! ib
    2642                 :             :    end do ! ik_ibz
    2643                 :             :  end do ! spin
    2644                 :             : 
    2645         [ +  + ]:          31 :  if (iet==1) then ! In order to output the mobility (only for L11, the conductivity, thus iet==1)
    2646                 :          23 :    max_occ = two / (self%nspinor * self%nsppol)
    2647                 :          23 :    fact0 = max_occ * (siemens_SI / Bohr_meter / cryst%ucvol) / 100
    2648                 :          23 :    fact = 100**3 / e_Cb
    2649                 :             : 
    2650   [ +  +  +  +  :         644 :    sigma_eh = fact0 * sigma_eh  ! siemens cm^-1
             +  +  +  + ]
    2651   [ +  +  +  +  :         230 :    fsum_eh = fsum_eh / cryst%ucvol
                   +  + ]
    2652                 :             : 
    2653                 :             :  ! Scale by the carrier concentration.
    2654         [ +  + ]:          46 :    do spin=1,nsppol
    2655         [ +  + ]:          92 :      do ieh=1,2
    2656                 :             :        call safe_div(sigma_eh(:,:,ieh,spin) * fact, &
    2657   [ +  +  +  + ]:         621 :                      self%n_ehst(ieh, spin, itemp) / cryst%ucvol / Bohr_meter**3, zero, mob_eh(:,:,ieh,spin))
    2658                 :             :      end do
    2659                 :             :    end do
    2660                 :             : 
    2661                 :             :    !Here I rescale sigma_eh to output correctly the Onsager coeff L11
    2662   [ +  +  +  +  :         644 :    sigma_eh = sigma_eh / fact0
             +  +  +  + ]
    2663                 :             :    end if
    2664                 :             :  !call xmpi_sum(sigma_eh, comm, ierr)
    2665                 :             :  !call xmpi_sum(onsager, comm, ierr)
    2666                 :             : 
    2667                 :             : ! max_occ = two / (self%nspinor * self%nsppol)
    2668                 :             : ! sigma_eh = max_occ * sigma_eh / cryst%ucvol
    2669                 :             :  !fsum_eh = fsum_eh / cryst%ucvol
    2670                 :             : 
    2671                 :          31 :  max_occ = two / (self%nspinor * self%nsppol)
    2672                 :             :  !Take into account spin degeneracy for all Onsager coefficient:
    2673   [ +  +  +  +  :         868 :  sigma_eh= max_occ * sigma_eh
             +  +  +  + ]
    2674                 :             : 
    2675                 :             : 
    2676                 :             : 
    2677                 :             : ! fact0 = max_occ * (siemens_SI / Bohr_meter / cryst%ucvol) / 100
    2678                 :             : ! fact = 100**3 / e_Cb
    2679                 :             : ! sigma_eh = fact0 * sigma_eh
    2680                 :             : 
    2681                 :             : 
    2682                 :             : 
    2683                 :             :  ! Scale by the carrier concentration.
    2684                 :             : ! do spin=1,nsppol
    2685                 :             : !   do ieh=1,2
    2686                 :             : !     call safe_div(sigma_eh(:,:,ieh,spin) * fact, &
    2687                 :             : !                   self%n_ehst(ieh, spin, itemp) / cryst%ucvol / Bohr_meter**3, zero, mob_eh(:,:,ieh,spin))
    2688                 :             : 
    2689                 :             : !check to find the bug
    2690                 :             : !call wrtout(std_out, " ieh, shape(sigma_eh) vol shape(mob_eh) ", pre_newlines=1, newlines=1)
    2691                 :             : !write (std_out,*)  ieh, shape(sigma_eh), cryst%ucvol, shape(mob_eh)
    2692                 :             : !call wrtout(std_out," check safe_div, in order: sigma_eh, self%n_ehst, cryst%ucvol, zero", pre_newlines=1, newlines=1)
    2693                 :             : !        write (std_out,*) sigma_eh(:,:,ieh,spin), self%n_ehst(ieh, spin, itemp), cryst%ucvol, zero
    2694                 :             : ! call flush_unit(std_out)
    2695                 :             : 
    2696                 :             : !        call safe_div(sigma_eh(:,:,ieh,spin), &
    2697                 :             : !                   self%n_ehst(ieh, spin, itemp) / cryst%ucvol, zero, mob_eh(:,:,ieh,spin))
    2698                 :             : !mob_eh(:,:,ieh,spin) = sigma_eh(:,:,ieh,spin)   / (self%n_ehst(ieh, spin, itemp) / cryst%ucvol)
    2699                 :             :            !check to find the bug
    2700                 :             : !           call wrtout(std_out," check safe_div, mob_eh: ", pre_newlines=1, newlines=1)
    2701                 :             : !        write (std_out,*) mob_eh(:,:,ieh,spin)
    2702                 :             : ! call flush_unit(std_out)
    2703                 :             : 
    2704                 :             : !   end do
    2705                 :             : ! end do
    2706                 :             : !In order to be able to compile, to have a value for the dummy argument mob_eh
    2707                 :             : 
    2708                 :             : !call wrtout(std_out, "shape(sigma_eh), sigma_eh,  shape(mob_eh), mob_eh ", pre_newlines=1, newlines=1)
    2709                 :             : !write (std_out,*) shape(sigma_eh),sigma_eh, shape(mob_eh), mob_eh
    2710                 :             : 
    2711                 :             : !mob_eh=zero
    2712                 :             : 
    2713                 :             : !mob_eh=sigma_eh
    2714                 :             : 
    2715                 :             : 
    2716                 :             : !max_occ = two / (self%nspinor * self%nsppol)
    2717                 :             : ! fact_sigma = max_occ * (siemens_SI / Bohr_meter) / 100.  ! Siemens / cm
    2718                 :             : ! fact_mob   = fact_sigma * 100.**3 / e_Cb * Bohr_meter**3 ! cm^2 / V / s
    2719                 :             : ! fact_sbk   = volt_SI * kb_HaK                           ! Volt / Kelvin
    2720                 :             : !   sigma_eh = fact_sigma * sigma_eh  ! siemens cm^-1
    2721                 :             :  !  mob_eh = fact_mob   * mob_eh  !
    2722                 :             : !call wrtout(std_out, "factors: fact_sigma, fact_mob", pre_newlines=1, newlines=1)
    2723                 :             : !   write (std_out,*) fact_sigma, fact_mob
    2724                 :             : 
    2725                 :          31 : end subroutine ibte_calc_tensors
    2726                 :             : !!***
    2727                 :             : 
    2728                 :             : ! Invert 3x3 matrix, copied from matr3inv
    2729                 :       52066 : pure subroutine inv33(aa, ait)
    2730                 :             : 
    2731                 :             : !Arguments ------------------------------------
    2732                 :             : !arrays
    2733                 :             :  real(dp),intent(in) :: aa(3,3)
    2734                 :             :  real(dp),intent(out) :: ait(3,3)
    2735                 :             : 
    2736                 :             : !Local variables-------------------------------
    2737                 :             : !scalars
    2738                 :             :  real(dp) :: dd,det,t1,t2,t3
    2739                 :             : 
    2740                 :             : ! *************************************************************************
    2741                 :             : 
    2742                 :       52066 :  t1 = aa(2,2) * aa(3,3) - aa(3,2) * aa(2,3)
    2743                 :       52066 :  t2 = aa(3,2) * aa(1,3) - aa(1,2) * aa(3,3)
    2744                 :       52066 :  t3 = aa(1,2) * aa(2,3) - aa(2,2) * aa(1,3)
    2745                 :       52066 :  det = aa(1,1) * t1 + aa(2,1) * t2 + aa(3,1) * t3
    2746                 :             : 
    2747                 :             :  ! Make sure matrix is not singular
    2748         [ +  + ]:       52066 :  if (abs(det) > 100 * tiny(one)) then
    2749                 :       15779 :    dd = one / det
    2750                 :       15779 :    ait(1,1) = t1 * dd
    2751                 :       15779 :    ait(2,1) = t2 * dd
    2752                 :       15779 :    ait(3,1) = t3 * dd
    2753                 :       15779 :    ait(1,2) = (aa(3,1)*aa(2,3)-aa(2,1)*aa(3,3)) * dd
    2754                 :       15779 :    ait(2,2) = (aa(1,1)*aa(3,3)-aa(3,1)*aa(1,3)) * dd
    2755                 :       15779 :    ait(3,2) = (aa(2,1)*aa(1,3)-aa(1,1)*aa(2,3)) * dd
    2756                 :       15779 :    ait(1,3) = (aa(2,1)*aa(3,2)-aa(3,1)*aa(2,2)) * dd
    2757                 :       15779 :    ait(2,3) = (aa(3,1)*aa(1,2)-aa(1,1)*aa(3,2)) * dd
    2758                 :       15779 :    ait(3,3) = (aa(1,1)*aa(2,2)-aa(2,1)*aa(1,2)) * dd
    2759   [ +  +  +  +  :      410254 :    ait = transpose(ait)
             +  +  +  + ]
    2760                 :             :  else
    2761                 :       36287 :    ait = zero
    2762                 :             :  end if
    2763                 :             : 
    2764                 :       52066 :  end subroutine inv33
    2765                 :             : 
    2766   [ -  +  +  -  :       51566 : end module m_rta
          +  -  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    2767                 :             : !!***
        

Generated by: LCOV version 2.3-1