LCOV - code coverage report
Current view: top level - shared/common/src/29_kpoints - m_htetra.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 70.4 % 1081 761
Test Date: 2026-11-09 22:30:52 Functions: 68.2 % 22 15
Branches: 74.5 % 1614 1203

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_htetra
       2                 :             : !! NAME
       3                 :             : !! m_htetra
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!  Module for tetrahedron integration of DOS and similar quantities
       7                 :             : !!  Uses some functions from a previous implementation by MJV
       8                 :             : !!
       9                 :             : !! COPYRIGHT
      10                 :             : !!  Copyright (C) 2010-2026 ABINIT group (HM,MJV)
      11                 :             : !!  This file is distributed under the terms of the
      12                 :             : !!  GNU General Public License, see ~abinit/COPYING
      13                 :             : !!  or http://www.gnu.org/copyleft/gpl.txt .
      14                 :             : !!
      15                 :             : !! TODO
      16                 :             : !!  1) Test more carefully the case of degenerate tethraedron
      17                 :             : !!  2) Add options to get only delta and/or theta ?
      18                 :             : !!
      19                 :             : !! SOURCE
      20                 :             : 
      21                 :             : #if defined HAVE_CONFIG_H
      22                 :             : #include "config.h"
      23                 :             : #endif
      24                 :             : 
      25                 :             : #include "abi_common.h"
      26                 :             : 
      27                 :             : module m_htetra
      28                 :             : 
      29                 :             :  use defs_basis
      30                 :             :  use m_abicore
      31                 :             :  use m_krank
      32                 :             :  use m_xmpi
      33                 :             :  use m_errors
      34                 :             : 
      35                 :             :  use m_fstrings,        only : sjoin, itoa, ftoa
      36                 :             :  use m_numeric_tools,   only : linspace
      37                 :             :  use m_simtet,          only : sim0onei, SIM0TWOI
      38                 :             : 
      39                 :             : implicit none
      40                 :             : 
      41                 :             : private
      42                 :             : !!***
      43                 :             : 
      44                 :             : integer, parameter :: TETRA_SIZE = 6
      45                 :             : integer, parameter :: TETRA_STEP = 6
      46                 :             : 
      47                 :             : !!****t* m_htetra/t_htetra_bucket
      48                 :             : !! NAME
      49                 :             : !! t_htetra_bucket
      50                 :             : !!
      51                 :             : !! FUNCTION
      52                 :             : !! Store a bunch of tetrahedra
      53                 :             : !!
      54                 :             : !! SOURCE
      55                 :             : 
      56                 :             : type :: htetra_bucket
      57                 :             : 
      58                 :             :   integer,allocatable :: indexes(:,:)
      59                 :             : 
      60                 :             : end type htetra_bucket
      61                 :             : !!***
      62                 :             : 
      63                 :             : !!****t* m_htetra/htetra_t
      64                 :             : !! NAME
      65                 :             : !! htetra_t
      66                 :             : !!
      67                 :             : !! FUNCTION
      68                 :             : !! tetrahedron geometry object
      69                 :             : !!
      70                 :             : !! SOURCE
      71                 :             : 
      72                 :             : type, public :: htetra_t
      73                 :             : 
      74                 :             :   integer :: opt
      75                 :             :   ! Option for the generation of tetrahedra
      76                 :             : 
      77                 :             :   integer :: nkibz
      78                 :             :   ! Number of points in the irreducible Brillouin zone
      79                 :             : 
      80                 :             :   integer :: nkbz
      81                 :             :   ! Number of points in the full Brillouin zone
      82                 :             : 
      83                 :             :   integer :: nbuckets
      84                 :             :   ! Number of buckets for the hash table
      85                 :             : 
      86                 :             :   integer :: nunique_tetra
      87                 :             :   ! Number of unique tetrahedron
      88                 :             : 
      89                 :             :   integer :: nibz_tetra
      90                 :             :   ! Number of ibz tetrahedron
      91                 :             : 
      92                 :             :   integer,allocatable :: tetra_total(:)
      93                 :             :   ! (%nbkibz)
      94                 :             :   ! Equivalent tetrahedra per kpoint (number of irred tetra times multiplicity)
      95                 :             : 
      96                 :             :   integer,allocatable :: tetra_count(:)
      97                 :             :   ! (%nbkibz)
      98                 :             :   ! Inequivalent tetrahedra per kpoint (number of irred tetra)
      99                 :             : 
     100                 :             :   integer,allocatable :: ibz_multiplicity(:)
     101                 :             :   ! (%nbkibz)
     102                 :             :   ! Multiplicity of each k-point
     103                 :             : 
     104                 :             :   real(dp)  :: vv
     105                 :             :   ! volume of the tetrahedra
     106                 :             : 
     107                 :             :   real(dp) :: klatt(3, 3)
     108                 :             :   ! reciprocal of equivalent supercell lattice vectors for full kpoint grid
     109                 :             : 
     110                 :             :   type(htetra_bucket),allocatable :: ibz(:)
     111                 :             :   ! indexes of the tetrahedra for each k-point
     112                 :             : 
     113                 :             :   type(htetra_bucket),allocatable :: unique_tetra(:)
     114                 :             :   ! indexes of the unique tetrahedra
     115                 :             : 
     116                 :             :   contains
     117                 :             : 
     118                 :             :   procedure :: init => htetra_init            ! Initialize the object
     119                 :             : 
     120                 :             :   procedure :: free  => htetra_free
     121                 :             :     ! Free memory
     122                 :             : 
     123                 :             :   procedure :: print => htetra_print
     124                 :             :     ! Print information about tetrahedron object
     125                 :             : 
     126                 :             :   procedure :: get_onewk => htetra_get_onewk
     127                 :             :     ! Calculate integration weights and their derivatives for a single k-point in the IBZ.
     128                 :             : 
     129                 :             :   procedure ::  get_onewk_wvals => htetra_get_onewk_wvals
     130                 :             :     ! Similar to tetra_get_onewk but receives arbitrary list of frequency points.
     131                 :             : 
     132                 :             :   procedure :: get_onewk_wvals_zinv => htetra_get_onewk_wvals_zinv
     133                 :             :     ! Calculate integration weights for 1/(z-E(k)) for a single k-point in the IBZ.
     134                 :             : 
     135                 :             :   procedure :: weights_wvals_zinv => htetra_weights_wvals_zinv
     136                 :             :     ! Same as above but return the weight on all the kpoints by looping over tetrahedra
     137                 :             : 
     138                 :             :   procedure :: wvals_weights => htetra_wvals_weights
     139                 :             :     ! Compute delta and theta on a list of energies for all kpoints
     140                 :             : 
     141                 :             :   procedure :: wvals_weights_delta => htetra_wvals_weights_delta
     142                 :             :     ! Compute delta on a list of energies for all kpoints
     143                 :             : 
     144                 :             :   procedure :: blochl_weights => htetra_blochl_weights
     145                 :             :     ! And interface to help to facilitate the transition to the new tetrahedron implementation
     146                 :             : 
     147                 :             : end type htetra_t
     148                 :             : !!***
     149                 :             : 
     150                 :             : !!***
     151                 :             : 
     152                 :             : contains
     153                 :             : !!***
     154                 :             : 
     155                 :             : !----------------------------------------------------------------------
     156                 :             : 
     157                 :             : !!****f* m_htetra/htetra_init
     158                 :             : !! NAME
     159                 :             : !! htetra_init
     160                 :             : !!
     161                 :             : !! FUNCTION
     162                 :             : !! get tetrahedra characterized by apexes
     163                 :             : !!
     164                 :             : !! INPUTS
     165                 :             : !!  bz2ibz(nkpt_fullbz)=indexes of irred kpoints equivalent to kpt_fullbz
     166                 :             : !!  gprimd(3,3) = reciprocal space vectors
     167                 :             : !!  klatt(3,3)=reciprocal of lattice vectors for full kpoint grid
     168                 :             : !!  kpt_fullbz(3,nkpt_fullbz)=kpoints in full brillouin zone
     169                 :             : !!  nkpt_fullbz=number of kpoints in full brillouin zone
     170                 :             : !!  options=1.generate 24 tetrahedra per k-point
     171                 :             : !!            faster but gives different results depending on the IBZ, small error for large grids
     172                 :             : !!          2.generate tetrahedra on the FBZ and map to IBZ
     173                 :             : !!            slower but same results for IBZ and FBZ.
     174                 :             : !!  comm= MPI communicator
     175                 :             : !!  [opt]= 1 for Togo's version, 2 for Blochl's version (default)
     176                 :             : !!
     177                 :             : !! OUTPUT
     178                 :             : !!  tetra%ibz(4,24,nkibz)=for each k-point, the indexes in the IBZ
     179                 :             : !!  tetra%vv = tetrahedron volume divided by full BZ volume
     180                 :             : !!
     181                 :             : !! SOURCE
     182                 :             : 
     183                 :         486 : subroutine htetra_init(tetra, bz2ibz, gprimd, klatt, kpt_fullbz, nkpt_fullbz, kpt_ibz, nkpt_ibz, &
     184                 :             :                        ierr, errorstring, comm, &
     185                 :             :                        opt) ! optional
     186                 :             : 
     187                 :             : !Arguments ------------------------------------
     188                 :             : !scalars
     189                 :             :  class(htetra_t),intent(out),target :: tetra
     190                 :             :  integer,intent(in) :: nkpt_fullbz, nkpt_ibz, comm
     191                 :             :  integer,optional,intent(in) :: opt
     192                 :             :  integer,intent(out) :: ierr
     193                 :             :  character(len=80),intent(out) :: errorstring
     194                 :             : !arrays
     195                 :             :  integer,intent(in) :: bz2ibz(nkpt_fullbz)
     196                 :             :  real(dp),intent(in) :: gprimd(3,3),klatt(3,3),kpt_fullbz(3,nkpt_fullbz),kpt_ibz(3,nkpt_ibz)
     197                 :             : 
     198                 :             : !Local variables-------------------------------
     199                 :             : !scalars
     200                 :             :  !type(octree_t) :: oct
     201                 :         243 :  type(krank_t) :: krank
     202                 :             :  integer :: ikpt2,isummit,itetra,jtetra
     203                 :             :  integer :: ikibz,ikbz,idiag,ihash,min_idiag,my_rank,nprocs
     204                 :             :  integer :: max_ntetra, ntetra
     205                 :             :  real(dp) :: rcvol,length,min_length
     206                 :             : !arrays
     207         [ +  - ]:         243 :  integer,allocatable,target :: indexes(:,:), tetra_hash_count(:)
     208                 :             :  integer :: tetra_ibz(4)
     209                 :             :  integer :: tetra_shifts(3,4,24,4)  ! 3 dimensions, 4 summits, 24 tetrahedra, 4 main diagonals
     210                 :             :  integer :: tetra_shifts_6(3,4,6,1) ! 3 dimensions, 4 summits, 6 tetrahedra, 4 main diagonals
     211                 :             :  integer :: main_diagonals(3,4), tetra_mibz(0:4)
     212                 :             :  real(dp)  :: k1(3),k2(3),k3(3),diag(3)
     213                 :             : ! *********************************************************************
     214                 :             : 
     215                 :             :  ! Use the shifts from kpclib developed by Atsushi Togo
     216                 :             :  ! This part is produced by a python script
     217                 :             :  ! This implementation is based on spglib and kpclib by Atsushi Togo
     218                 :             :  ! after a discussion with hin on the APS 2019 where he provided
     219                 :             :  ! details of his implementation.
     220                 :             :  ! Note that we don't use it in production as we found that is approach, although faster than the original
     221                 :             :  ! one proposed by Blochl (and implemented by MJV) does not preserve symmetries that is calculations done on the full BZ
     222                 :             :  ! and the IBZ do not produce the same result. The diff, however, decreases if the sampling is densified.
     223                 :             : 
     224         [ +  + ]:         972 :  tetra_shifts(:, 1, 1,1) = [  0,  0,  0]
     225         [ +  + ]:         972 :  tetra_shifts(:, 2, 1,1) = [  1,  0,  0]
     226         [ +  + ]:         972 :  tetra_shifts(:, 3, 1,1) = [  1,  1,  0]
     227         [ +  + ]:         972 :  tetra_shifts(:, 4, 1,1) = [  1,  1,  1]
     228         [ +  + ]:         972 :  tetra_shifts(:, 1, 2,1) = [  0,  0,  0]
     229         [ +  + ]:         972 :  tetra_shifts(:, 2, 2,1) = [  1,  0,  0]
     230         [ +  + ]:         972 :  tetra_shifts(:, 3, 2,1) = [  1,  0,  1]
     231         [ +  + ]:         972 :  tetra_shifts(:, 4, 2,1) = [  1,  1,  1]
     232         [ +  + ]:         972 :  tetra_shifts(:, 1, 3,1) = [  0,  0,  0]
     233         [ +  + ]:         972 :  tetra_shifts(:, 2, 3,1) = [  0,  1,  0]
     234         [ +  + ]:         972 :  tetra_shifts(:, 3, 3,1) = [  1,  1,  0]
     235         [ +  + ]:         972 :  tetra_shifts(:, 4, 3,1) = [  1,  1,  1]
     236         [ +  + ]:         972 :  tetra_shifts(:, 1, 4,1) = [  0,  0,  0]
     237         [ +  + ]:         972 :  tetra_shifts(:, 2, 4,1) = [  0,  1,  0]
     238         [ +  + ]:         972 :  tetra_shifts(:, 3, 4,1) = [  0,  1,  1]
     239         [ +  + ]:         972 :  tetra_shifts(:, 4, 4,1) = [  1,  1,  1]
     240         [ +  + ]:         972 :  tetra_shifts(:, 1, 5,1) = [  0,  0,  0]
     241         [ +  + ]:         972 :  tetra_shifts(:, 2, 5,1) = [  0,  0,  1]
     242         [ +  + ]:         972 :  tetra_shifts(:, 3, 5,1) = [  1,  0,  1]
     243         [ +  + ]:         972 :  tetra_shifts(:, 4, 5,1) = [  1,  1,  1]
     244         [ +  + ]:         972 :  tetra_shifts(:, 1, 6,1) = [  0,  0,  0]
     245         [ +  + ]:         972 :  tetra_shifts(:, 2, 6,1) = [  0,  0,  1]
     246         [ +  + ]:         972 :  tetra_shifts(:, 3, 6,1) = [  0,  1,  1]
     247         [ +  + ]:         972 :  tetra_shifts(:, 4, 6,1) = [  1,  1,  1]
     248         [ +  + ]:         972 :  tetra_shifts(:, 1, 7,1) = [  0,  0,  0]
     249         [ +  + ]:         972 :  tetra_shifts(:, 2, 7,1) = [  0,  1,  0]
     250         [ +  + ]:         972 :  tetra_shifts(:, 3, 7,1) = [  0,  1,  1]
     251         [ +  + ]:         972 :  tetra_shifts(:, 4, 7,1) = [ -1,  0,  0]
     252         [ +  + ]:         972 :  tetra_shifts(:, 1, 8,1) = [  0,  0,  0]
     253         [ +  + ]:         972 :  tetra_shifts(:, 2, 8,1) = [  0,  0,  1]
     254         [ +  + ]:         972 :  tetra_shifts(:, 3, 8,1) = [  0,  1,  1]
     255         [ +  + ]:         972 :  tetra_shifts(:, 4, 8,1) = [ -1,  0,  0]
     256         [ +  + ]:         972 :  tetra_shifts(:, 1, 9,1) = [  0,  0,  0]
     257         [ +  + ]:         972 :  tetra_shifts(:, 2, 9,1) = [  1,  0,  0]
     258         [ +  + ]:         972 :  tetra_shifts(:, 3, 9,1) = [  1,  0,  1]
     259         [ +  + ]:         972 :  tetra_shifts(:, 4, 9,1) = [  0, -1,  0]
     260         [ +  + ]:         972 :  tetra_shifts(:, 1,10,1) = [  0,  0,  0]
     261         [ +  + ]:         972 :  tetra_shifts(:, 2,10,1) = [  0,  0,  1]
     262         [ +  + ]:         972 :  tetra_shifts(:, 3,10,1) = [  1,  0,  1]
     263         [ +  + ]:         972 :  tetra_shifts(:, 4,10,1) = [  0, -1,  0]
     264         [ +  + ]:         972 :  tetra_shifts(:, 1,11,1) = [  0,  0,  0]
     265         [ +  + ]:         972 :  tetra_shifts(:, 2,11,1) = [  0,  0,  1]
     266         [ +  + ]:         972 :  tetra_shifts(:, 3,11,1) = [ -1, -1,  0]
     267         [ +  + ]:         972 :  tetra_shifts(:, 4,11,1) = [  0, -1,  0]
     268         [ +  + ]:         972 :  tetra_shifts(:, 1,12,1) = [  0,  0,  0]
     269         [ +  + ]:         972 :  tetra_shifts(:, 2,12,1) = [  0,  0,  1]
     270         [ +  + ]:         972 :  tetra_shifts(:, 3,12,1) = [ -1, -1,  0]
     271         [ +  + ]:         972 :  tetra_shifts(:, 4,12,1) = [ -1,  0,  0]
     272         [ +  + ]:         972 :  tetra_shifts(:, 1,13,1) = [  0,  0,  0]
     273         [ +  + ]:         972 :  tetra_shifts(:, 2,13,1) = [  1,  0,  0]
     274         [ +  + ]:         972 :  tetra_shifts(:, 3,13,1) = [  1,  1,  0]
     275         [ +  + ]:         972 :  tetra_shifts(:, 4,13,1) = [  0,  0, -1]
     276         [ +  + ]:         972 :  tetra_shifts(:, 1,14,1) = [  0,  0,  0]
     277         [ +  + ]:         972 :  tetra_shifts(:, 2,14,1) = [  0,  1,  0]
     278         [ +  + ]:         972 :  tetra_shifts(:, 3,14,1) = [  1,  1,  0]
     279         [ +  + ]:         972 :  tetra_shifts(:, 4,14,1) = [  0,  0, -1]
     280         [ +  + ]:         972 :  tetra_shifts(:, 1,15,1) = [  0,  0,  0]
     281         [ +  + ]:         972 :  tetra_shifts(:, 2,15,1) = [  0,  1,  0]
     282         [ +  + ]:         972 :  tetra_shifts(:, 3,15,1) = [ -1,  0, -1]
     283         [ +  + ]:         972 :  tetra_shifts(:, 4,15,1) = [  0,  0, -1]
     284         [ +  + ]:         972 :  tetra_shifts(:, 1,16,1) = [  0,  0,  0]
     285         [ +  + ]:         972 :  tetra_shifts(:, 2,16,1) = [  0,  1,  0]
     286         [ +  + ]:         972 :  tetra_shifts(:, 3,16,1) = [ -1,  0, -1]
     287         [ +  + ]:         972 :  tetra_shifts(:, 4,16,1) = [ -1,  0,  0]
     288         [ +  + ]:         972 :  tetra_shifts(:, 1,17,1) = [  0,  0,  0]
     289         [ +  + ]:         972 :  tetra_shifts(:, 2,17,1) = [  1,  0,  0]
     290         [ +  + ]:         972 :  tetra_shifts(:, 3,17,1) = [  0, -1, -1]
     291         [ +  + ]:         972 :  tetra_shifts(:, 4,17,1) = [  0,  0, -1]
     292         [ +  + ]:         972 :  tetra_shifts(:, 1,18,1) = [  0,  0,  0]
     293         [ +  + ]:         972 :  tetra_shifts(:, 2,18,1) = [  1,  0,  0]
     294         [ +  + ]:         972 :  tetra_shifts(:, 3,18,1) = [  0, -1, -1]
     295         [ +  + ]:         972 :  tetra_shifts(:, 4,18,1) = [  0, -1,  0]
     296         [ +  + ]:         972 :  tetra_shifts(:, 1,19,1) = [  0,  0,  0]
     297         [ +  + ]:         972 :  tetra_shifts(:, 2,19,1) = [ -1, -1, -1]
     298         [ +  + ]:         972 :  tetra_shifts(:, 3,19,1) = [  0, -1, -1]
     299         [ +  + ]:         972 :  tetra_shifts(:, 4,19,1) = [  0,  0, -1]
     300         [ +  + ]:         972 :  tetra_shifts(:, 1,20,1) = [  0,  0,  0]
     301         [ +  + ]:         972 :  tetra_shifts(:, 2,20,1) = [ -1, -1, -1]
     302         [ +  + ]:         972 :  tetra_shifts(:, 3,20,1) = [  0, -1, -1]
     303         [ +  + ]:         972 :  tetra_shifts(:, 4,20,1) = [  0, -1,  0]
     304         [ +  + ]:         972 :  tetra_shifts(:, 1,21,1) = [  0,  0,  0]
     305         [ +  + ]:         972 :  tetra_shifts(:, 2,21,1) = [ -1, -1, -1]
     306         [ +  + ]:         972 :  tetra_shifts(:, 3,21,1) = [ -1,  0, -1]
     307         [ +  + ]:         972 :  tetra_shifts(:, 4,21,1) = [  0,  0, -1]
     308         [ +  + ]:         972 :  tetra_shifts(:, 1,22,1) = [  0,  0,  0]
     309         [ +  + ]:         972 :  tetra_shifts(:, 2,22,1) = [ -1, -1, -1]
     310         [ +  + ]:         972 :  tetra_shifts(:, 3,22,1) = [ -1,  0, -1]
     311         [ +  + ]:         972 :  tetra_shifts(:, 4,22,1) = [ -1,  0,  0]
     312         [ +  + ]:         972 :  tetra_shifts(:, 1,23,1) = [  0,  0,  0]
     313         [ +  + ]:         972 :  tetra_shifts(:, 2,23,1) = [ -1, -1, -1]
     314         [ +  + ]:         972 :  tetra_shifts(:, 3,23,1) = [ -1, -1,  0]
     315         [ +  + ]:         972 :  tetra_shifts(:, 4,23,1) = [  0, -1,  0]
     316         [ +  + ]:         972 :  tetra_shifts(:, 1,24,1) = [  0,  0,  0]
     317         [ +  + ]:         972 :  tetra_shifts(:, 2,24,1) = [ -1, -1, -1]
     318         [ +  + ]:         972 :  tetra_shifts(:, 3,24,1) = [ -1, -1,  0]
     319         [ +  + ]:         972 :  tetra_shifts(:, 4,24,1) = [ -1,  0,  0]
     320         [ +  + ]:         972 :  tetra_shifts(:, 1, 1,2) = [  0,  0,  0]
     321         [ +  + ]:         972 :  tetra_shifts(:, 2, 1,2) = [  1,  0,  0]
     322         [ +  + ]:         972 :  tetra_shifts(:, 3, 1,2) = [  0,  1,  0]
     323         [ +  + ]:         972 :  tetra_shifts(:, 4, 1,2) = [  0,  1,  1]
     324         [ +  + ]:         972 :  tetra_shifts(:, 1, 2,2) = [  0,  0,  0]
     325         [ +  + ]:         972 :  tetra_shifts(:, 2, 2,2) = [  1,  0,  0]
     326         [ +  + ]:         972 :  tetra_shifts(:, 3, 2,2) = [  0,  0,  1]
     327         [ +  + ]:         972 :  tetra_shifts(:, 4, 2,2) = [  0,  1,  1]
     328         [ +  + ]:         972 :  tetra_shifts(:, 1, 3,2) = [  0,  0,  0]
     329         [ +  + ]:         972 :  tetra_shifts(:, 2, 3,2) = [ -1,  1,  0]
     330         [ +  + ]:         972 :  tetra_shifts(:, 3, 3,2) = [ -1,  1,  1]
     331         [ +  + ]:         972 :  tetra_shifts(:, 4, 3,2) = [ -1,  0,  0]
     332         [ +  + ]:         972 :  tetra_shifts(:, 1, 4,2) = [  0,  0,  0]
     333         [ +  + ]:         972 :  tetra_shifts(:, 2, 4,2) = [ -1,  0,  1]
     334         [ +  + ]:         972 :  tetra_shifts(:, 3, 4,2) = [ -1,  1,  1]
     335         [ +  + ]:         972 :  tetra_shifts(:, 4, 4,2) = [ -1,  0,  0]
     336         [ +  + ]:         972 :  tetra_shifts(:, 1, 5,2) = [  0,  0,  0]
     337         [ +  + ]:         972 :  tetra_shifts(:, 2, 5,2) = [ -1,  1,  0]
     338         [ +  + ]:         972 :  tetra_shifts(:, 3, 5,2) = [  0,  1,  0]
     339         [ +  + ]:         972 :  tetra_shifts(:, 4, 5,2) = [ -1,  1,  1]
     340         [ +  + ]:         972 :  tetra_shifts(:, 1, 6,2) = [  0,  0,  0]
     341         [ +  + ]:         972 :  tetra_shifts(:, 2, 6,2) = [  0,  1,  0]
     342         [ +  + ]:         972 :  tetra_shifts(:, 3, 6,2) = [ -1,  1,  1]
     343         [ +  + ]:         972 :  tetra_shifts(:, 4, 6,2) = [  0,  1,  1]
     344         [ +  + ]:         972 :  tetra_shifts(:, 1, 7,2) = [  0,  0,  0]
     345         [ +  + ]:         972 :  tetra_shifts(:, 2, 7,2) = [ -1,  0,  1]
     346         [ +  + ]:         972 :  tetra_shifts(:, 3, 7,2) = [  0,  0,  1]
     347         [ +  + ]:         972 :  tetra_shifts(:, 4, 7,2) = [ -1,  1,  1]
     348         [ +  + ]:         972 :  tetra_shifts(:, 1, 8,2) = [  0,  0,  0]
     349         [ +  + ]:         972 :  tetra_shifts(:, 2, 8,2) = [  0,  0,  1]
     350         [ +  + ]:         972 :  tetra_shifts(:, 3, 8,2) = [ -1,  1,  1]
     351         [ +  + ]:         972 :  tetra_shifts(:, 4, 8,2) = [  0,  1,  1]
     352         [ +  + ]:         972 :  tetra_shifts(:, 1, 9,2) = [  0,  0,  0]
     353         [ +  + ]:         972 :  tetra_shifts(:, 2, 9,2) = [  0,  0,  1]
     354         [ +  + ]:         972 :  tetra_shifts(:, 3, 9,2) = [  0, -1,  0]
     355         [ +  + ]:         972 :  tetra_shifts(:, 4, 9,2) = [  1, -1,  0]
     356         [ +  + ]:         972 :  tetra_shifts(:, 1,10,2) = [  0,  0,  0]
     357         [ +  + ]:         972 :  tetra_shifts(:, 2,10,2) = [  1,  0,  0]
     358         [ +  + ]:         972 :  tetra_shifts(:, 3,10,2) = [  0,  0,  1]
     359         [ +  + ]:         972 :  tetra_shifts(:, 4,10,2) = [  1, -1,  0]
     360         [ +  + ]:         972 :  tetra_shifts(:, 1,11,2) = [  0,  0,  0]
     361         [ +  + ]:         972 :  tetra_shifts(:, 2,11,2) = [ -1,  0,  1]
     362         [ +  + ]:         972 :  tetra_shifts(:, 3,11,2) = [  0, -1,  0]
     363         [ +  + ]:         972 :  tetra_shifts(:, 4,11,2) = [ -1,  0,  0]
     364         [ +  + ]:         972 :  tetra_shifts(:, 1,12,2) = [  0,  0,  0]
     365         [ +  + ]:         972 :  tetra_shifts(:, 2,12,2) = [ -1,  0,  1]
     366         [ +  + ]:         972 :  tetra_shifts(:, 3,12,2) = [  0,  0,  1]
     367         [ +  + ]:         972 :  tetra_shifts(:, 4,12,2) = [  0, -1,  0]
     368         [ +  + ]:         972 :  tetra_shifts(:, 1,13,2) = [  0,  0,  0]
     369         [ +  + ]:         972 :  tetra_shifts(:, 2,13,2) = [  0,  1,  0]
     370         [ +  + ]:         972 :  tetra_shifts(:, 3,13,2) = [  0,  0, -1]
     371         [ +  + ]:         972 :  tetra_shifts(:, 4,13,2) = [  1,  0, -1]
     372         [ +  + ]:         972 :  tetra_shifts(:, 1,14,2) = [  0,  0,  0]
     373         [ +  + ]:         972 :  tetra_shifts(:, 2,14,2) = [  1,  0,  0]
     374         [ +  + ]:         972 :  tetra_shifts(:, 3,14,2) = [  0,  1,  0]
     375         [ +  + ]:         972 :  tetra_shifts(:, 4,14,2) = [  1,  0, -1]
     376         [ +  + ]:         972 :  tetra_shifts(:, 1,15,2) = [  0,  0,  0]
     377         [ +  + ]:         972 :  tetra_shifts(:, 2,15,2) = [ -1,  1,  0]
     378         [ +  + ]:         972 :  tetra_shifts(:, 3,15,2) = [  0,  0, -1]
     379         [ +  + ]:         972 :  tetra_shifts(:, 4,15,2) = [ -1,  0,  0]
     380         [ +  + ]:         972 :  tetra_shifts(:, 1,16,2) = [  0,  0,  0]
     381         [ +  + ]:         972 :  tetra_shifts(:, 2,16,2) = [ -1,  1,  0]
     382         [ +  + ]:         972 :  tetra_shifts(:, 3,16,2) = [  0,  1,  0]
     383         [ +  + ]:         972 :  tetra_shifts(:, 4,16,2) = [  0,  0, -1]
     384         [ +  + ]:         972 :  tetra_shifts(:, 1,17,2) = [  0,  0,  0]
     385         [ +  + ]:         972 :  tetra_shifts(:, 2,17,2) = [  0, -1, -1]
     386         [ +  + ]:         972 :  tetra_shifts(:, 3,17,2) = [  1, -1, -1]
     387         [ +  + ]:         972 :  tetra_shifts(:, 4,17,2) = [  0,  0, -1]
     388         [ +  + ]:         972 :  tetra_shifts(:, 1,18,2) = [  0,  0,  0]
     389         [ +  + ]:         972 :  tetra_shifts(:, 2,18,2) = [  0, -1, -1]
     390         [ +  + ]:         972 :  tetra_shifts(:, 3,18,2) = [  1, -1, -1]
     391         [ +  + ]:         972 :  tetra_shifts(:, 4,18,2) = [  0, -1,  0]
     392         [ +  + ]:         972 :  tetra_shifts(:, 1,19,2) = [  0,  0,  0]
     393         [ +  + ]:         972 :  tetra_shifts(:, 2,19,2) = [  1, -1, -1]
     394         [ +  + ]:         972 :  tetra_shifts(:, 3,19,2) = [  0,  0, -1]
     395         [ +  + ]:         972 :  tetra_shifts(:, 4,19,2) = [  1,  0, -1]
     396         [ +  + ]:         972 :  tetra_shifts(:, 1,20,2) = [  0,  0,  0]
     397         [ +  + ]:         972 :  tetra_shifts(:, 2,20,2) = [  1,  0,  0]
     398         [ +  + ]:         972 :  tetra_shifts(:, 3,20,2) = [  1, -1, -1]
     399         [ +  + ]:         972 :  tetra_shifts(:, 4,20,2) = [  1,  0, -1]
     400         [ +  + ]:         972 :  tetra_shifts(:, 1,21,2) = [  0,  0,  0]
     401         [ +  + ]:         972 :  tetra_shifts(:, 2,21,2) = [  1, -1, -1]
     402         [ +  + ]:         972 :  tetra_shifts(:, 3,21,2) = [  0, -1,  0]
     403         [ +  + ]:         972 :  tetra_shifts(:, 4,21,2) = [  1, -1,  0]
     404         [ +  + ]:         972 :  tetra_shifts(:, 1,22,2) = [  0,  0,  0]
     405         [ +  + ]:         972 :  tetra_shifts(:, 2,22,2) = [  1,  0,  0]
     406         [ +  + ]:         972 :  tetra_shifts(:, 3,22,2) = [  1, -1, -1]
     407         [ +  + ]:         972 :  tetra_shifts(:, 4,22,2) = [  1, -1,  0]
     408         [ +  + ]:         972 :  tetra_shifts(:, 1,23,2) = [  0,  0,  0]
     409         [ +  + ]:         972 :  tetra_shifts(:, 2,23,2) = [  0, -1, -1]
     410         [ +  + ]:         972 :  tetra_shifts(:, 3,23,2) = [  0,  0, -1]
     411         [ +  + ]:         972 :  tetra_shifts(:, 4,23,2) = [ -1,  0,  0]
     412         [ +  + ]:         972 :  tetra_shifts(:, 1,24,2) = [  0,  0,  0]
     413         [ +  + ]:         972 :  tetra_shifts(:, 2,24,2) = [  0, -1, -1]
     414         [ +  + ]:         972 :  tetra_shifts(:, 3,24,2) = [  0, -1,  0]
     415         [ +  + ]:         972 :  tetra_shifts(:, 4,24,2) = [ -1,  0,  0]
     416         [ +  + ]:         972 :  tetra_shifts(:, 1, 1,3) = [  0,  0,  0]
     417         [ +  + ]:         972 :  tetra_shifts(:, 2, 1,3) = [  1,  0,  0]
     418         [ +  + ]:         972 :  tetra_shifts(:, 3, 1,3) = [  0,  1,  0]
     419         [ +  + ]:         972 :  tetra_shifts(:, 4, 1,3) = [  1,  0,  1]
     420         [ +  + ]:         972 :  tetra_shifts(:, 1, 2,3) = [  0,  0,  0]
     421         [ +  + ]:         972 :  tetra_shifts(:, 2, 2,3) = [  0,  1,  0]
     422         [ +  + ]:         972 :  tetra_shifts(:, 3, 2,3) = [  0,  0,  1]
     423         [ +  + ]:         972 :  tetra_shifts(:, 4, 2,3) = [  1,  0,  1]
     424         [ +  + ]:         972 :  tetra_shifts(:, 1, 3,3) = [  0,  0,  0]
     425         [ +  + ]:         972 :  tetra_shifts(:, 2, 3,3) = [ -1,  1,  0]
     426         [ +  + ]:         972 :  tetra_shifts(:, 3, 3,3) = [  0,  0,  1]
     427         [ +  + ]:         972 :  tetra_shifts(:, 4, 3,3) = [ -1,  0,  0]
     428         [ +  + ]:         972 :  tetra_shifts(:, 1, 4,3) = [  0,  0,  0]
     429         [ +  + ]:         972 :  tetra_shifts(:, 2, 4,3) = [ -1,  1,  0]
     430         [ +  + ]:         972 :  tetra_shifts(:, 3, 4,3) = [  0,  1,  0]
     431         [ +  + ]:         972 :  tetra_shifts(:, 4, 4,3) = [  0,  0,  1]
     432         [ +  + ]:         972 :  tetra_shifts(:, 1, 5,3) = [  0,  0,  0]
     433         [ +  + ]:         972 :  tetra_shifts(:, 2, 5,3) = [  1, -1,  1]
     434         [ +  + ]:         972 :  tetra_shifts(:, 3, 5,3) = [  0, -1,  0]
     435         [ +  + ]:         972 :  tetra_shifts(:, 4, 5,3) = [  1, -1,  0]
     436         [ +  + ]:         972 :  tetra_shifts(:, 1, 6,3) = [  0,  0,  0]
     437         [ +  + ]:         972 :  tetra_shifts(:, 2, 6,3) = [  0, -1,  1]
     438         [ +  + ]:         972 :  tetra_shifts(:, 3, 6,3) = [  1, -1,  1]
     439         [ +  + ]:         972 :  tetra_shifts(:, 4, 6,3) = [  0, -1,  0]
     440         [ +  + ]:         972 :  tetra_shifts(:, 1, 7,3) = [  0,  0,  0]
     441         [ +  + ]:         972 :  tetra_shifts(:, 2, 7,3) = [  1,  0,  0]
     442         [ +  + ]:         972 :  tetra_shifts(:, 3, 7,3) = [  1, -1,  1]
     443         [ +  + ]:         972 :  tetra_shifts(:, 4, 7,3) = [  1, -1,  0]
     444         [ +  + ]:         972 :  tetra_shifts(:, 1, 8,3) = [  0,  0,  0]
     445         [ +  + ]:         972 :  tetra_shifts(:, 2, 8,3) = [  1,  0,  0]
     446         [ +  + ]:         972 :  tetra_shifts(:, 3, 8,3) = [  1, -1,  1]
     447         [ +  + ]:         972 :  tetra_shifts(:, 4, 8,3) = [  1,  0,  1]
     448         [ +  + ]:         972 :  tetra_shifts(:, 1, 9,3) = [  0,  0,  0]
     449         [ +  + ]:         972 :  tetra_shifts(:, 2, 9,3) = [  0, -1,  1]
     450         [ +  + ]:         972 :  tetra_shifts(:, 3, 9,3) = [  1, -1,  1]
     451         [ +  + ]:         972 :  tetra_shifts(:, 4, 9,3) = [  0,  0,  1]
     452         [ +  + ]:         972 :  tetra_shifts(:, 1,10,3) = [  0,  0,  0]
     453         [ +  + ]:         972 :  tetra_shifts(:, 2,10,3) = [  1, -1,  1]
     454         [ +  + ]:         972 :  tetra_shifts(:, 3,10,3) = [  0,  0,  1]
     455         [ +  + ]:         972 :  tetra_shifts(:, 4,10,3) = [  1,  0,  1]
     456         [ +  + ]:         972 :  tetra_shifts(:, 1,11,3) = [  0,  0,  0]
     457         [ +  + ]:         972 :  tetra_shifts(:, 2,11,3) = [  0, -1,  1]
     458         [ +  + ]:         972 :  tetra_shifts(:, 3,11,3) = [  0, -1,  0]
     459         [ +  + ]:         972 :  tetra_shifts(:, 4,11,3) = [ -1,  0,  0]
     460         [ +  + ]:         972 :  tetra_shifts(:, 1,12,3) = [  0,  0,  0]
     461         [ +  + ]:         972 :  tetra_shifts(:, 2,12,3) = [  0, -1,  1]
     462         [ +  + ]:         972 :  tetra_shifts(:, 3,12,3) = [  0,  0,  1]
     463         [ +  + ]:         972 :  tetra_shifts(:, 4,12,3) = [ -1,  0,  0]
     464         [ +  + ]:         972 :  tetra_shifts(:, 1,13,3) = [  0,  0,  0]
     465         [ +  + ]:         972 :  tetra_shifts(:, 2,13,3) = [  1,  0,  0]
     466         [ +  + ]:         972 :  tetra_shifts(:, 3,13,3) = [  0,  0, -1]
     467         [ +  + ]:         972 :  tetra_shifts(:, 4,13,3) = [  0,  1, -1]
     468         [ +  + ]:         972 :  tetra_shifts(:, 1,14,3) = [  0,  0,  0]
     469         [ +  + ]:         972 :  tetra_shifts(:, 2,14,3) = [  1,  0,  0]
     470         [ +  + ]:         972 :  tetra_shifts(:, 3,14,3) = [  0,  1,  0]
     471         [ +  + ]:         972 :  tetra_shifts(:, 4,14,3) = [  0,  1, -1]
     472         [ +  + ]:         972 :  tetra_shifts(:, 1,15,3) = [  0,  0,  0]
     473         [ +  + ]:         972 :  tetra_shifts(:, 2,15,3) = [ -1,  0, -1]
     474         [ +  + ]:         972 :  tetra_shifts(:, 3,15,3) = [  0,  0, -1]
     475         [ +  + ]:         972 :  tetra_shifts(:, 4,15,3) = [ -1,  1, -1]
     476         [ +  + ]:         972 :  tetra_shifts(:, 1,16,3) = [  0,  0,  0]
     477         [ +  + ]:         972 :  tetra_shifts(:, 2,16,3) = [ -1,  0, -1]
     478         [ +  + ]:         972 :  tetra_shifts(:, 3,16,3) = [ -1,  1, -1]
     479         [ +  + ]:         972 :  tetra_shifts(:, 4,16,3) = [ -1,  0,  0]
     480         [ +  + ]:         972 :  tetra_shifts(:, 1,17,3) = [  0,  0,  0]
     481         [ +  + ]:         972 :  tetra_shifts(:, 2,17,3) = [  0,  0, -1]
     482         [ +  + ]:         972 :  tetra_shifts(:, 3,17,3) = [ -1,  1, -1]
     483         [ +  + ]:         972 :  tetra_shifts(:, 4,17,3) = [  0,  1, -1]
     484         [ +  + ]:         972 :  tetra_shifts(:, 1,18,3) = [  0,  0,  0]
     485         [ +  + ]:         972 :  tetra_shifts(:, 2,18,3) = [  0,  1,  0]
     486         [ +  + ]:         972 :  tetra_shifts(:, 3,18,3) = [ -1,  1, -1]
     487         [ +  + ]:         972 :  tetra_shifts(:, 4,18,3) = [  0,  1, -1]
     488         [ +  + ]:         972 :  tetra_shifts(:, 1,19,3) = [  0,  0,  0]
     489         [ +  + ]:         972 :  tetra_shifts(:, 2,19,3) = [ -1,  1,  0]
     490         [ +  + ]:         972 :  tetra_shifts(:, 3,19,3) = [ -1,  1, -1]
     491         [ +  + ]:         972 :  tetra_shifts(:, 4,19,3) = [ -1,  0,  0]
     492         [ +  + ]:         972 :  tetra_shifts(:, 1,20,3) = [  0,  0,  0]
     493         [ +  + ]:         972 :  tetra_shifts(:, 2,20,3) = [ -1,  1,  0]
     494         [ +  + ]:         972 :  tetra_shifts(:, 3,20,3) = [  0,  1,  0]
     495         [ +  + ]:         972 :  tetra_shifts(:, 4,20,3) = [ -1,  1, -1]
     496         [ +  + ]:         972 :  tetra_shifts(:, 1,21,3) = [  0,  0,  0]
     497         [ +  + ]:         972 :  tetra_shifts(:, 2,21,3) = [  0,  0, -1]
     498         [ +  + ]:         972 :  tetra_shifts(:, 3,21,3) = [  0, -1,  0]
     499         [ +  + ]:         972 :  tetra_shifts(:, 4,21,3) = [  1, -1,  0]
     500         [ +  + ]:         972 :  tetra_shifts(:, 1,22,3) = [  0,  0,  0]
     501         [ +  + ]:         972 :  tetra_shifts(:, 2,22,3) = [  1,  0,  0]
     502         [ +  + ]:         972 :  tetra_shifts(:, 3,22,3) = [  0,  0, -1]
     503         [ +  + ]:         972 :  tetra_shifts(:, 4,22,3) = [  1, -1,  0]
     504         [ +  + ]:         972 :  tetra_shifts(:, 1,23,3) = [  0,  0,  0]
     505         [ +  + ]:         972 :  tetra_shifts(:, 2,23,3) = [ -1,  0, -1]
     506         [ +  + ]:         972 :  tetra_shifts(:, 3,23,3) = [  0,  0, -1]
     507         [ +  + ]:         972 :  tetra_shifts(:, 4,23,3) = [  0, -1,  0]
     508         [ +  + ]:         972 :  tetra_shifts(:, 1,24,3) = [  0,  0,  0]
     509         [ +  + ]:         972 :  tetra_shifts(:, 2,24,3) = [ -1,  0, -1]
     510         [ +  + ]:         972 :  tetra_shifts(:, 3,24,3) = [  0, -1,  0]
     511         [ +  + ]:         972 :  tetra_shifts(:, 4,24,3) = [ -1,  0,  0]
     512         [ +  + ]:         972 :  tetra_shifts(:, 1, 1,4) = [  0,  0,  0]
     513         [ +  + ]:         972 :  tetra_shifts(:, 2, 1,4) = [  1,  0,  0]
     514         [ +  + ]:         972 :  tetra_shifts(:, 3, 1,4) = [  1,  1,  0]
     515         [ +  + ]:         972 :  tetra_shifts(:, 4, 1,4) = [  0,  0,  1]
     516         [ +  + ]:         972 :  tetra_shifts(:, 1, 2,4) = [  0,  0,  0]
     517         [ +  + ]:         972 :  tetra_shifts(:, 2, 2,4) = [  0,  1,  0]
     518         [ +  + ]:         972 :  tetra_shifts(:, 3, 2,4) = [  1,  1,  0]
     519         [ +  + ]:         972 :  tetra_shifts(:, 4, 2,4) = [  0,  0,  1]
     520         [ +  + ]:         972 :  tetra_shifts(:, 1, 3,4) = [  0,  0,  0]
     521         [ +  + ]:         972 :  tetra_shifts(:, 2, 3,4) = [  0,  1,  0]
     522         [ +  + ]:         972 :  tetra_shifts(:, 3, 3,4) = [ -1,  0,  1]
     523         [ +  + ]:         972 :  tetra_shifts(:, 4, 3,4) = [ -1,  0,  0]
     524         [ +  + ]:         972 :  tetra_shifts(:, 1, 4,4) = [  0,  0,  0]
     525         [ +  + ]:         972 :  tetra_shifts(:, 2, 4,4) = [  0,  1,  0]
     526         [ +  + ]:         972 :  tetra_shifts(:, 3, 4,4) = [ -1,  0,  1]
     527         [ +  + ]:         972 :  tetra_shifts(:, 4, 4,4) = [  0,  0,  1]
     528         [ +  + ]:         972 :  tetra_shifts(:, 1, 5,4) = [  0,  0,  0]
     529         [ +  + ]:         972 :  tetra_shifts(:, 2, 5,4) = [  1,  0,  0]
     530         [ +  + ]:         972 :  tetra_shifts(:, 3, 5,4) = [  0, -1,  1]
     531         [ +  + ]:         972 :  tetra_shifts(:, 4, 5,4) = [  0, -1,  0]
     532         [ +  + ]:         972 :  tetra_shifts(:, 1, 6,4) = [  0,  0,  0]
     533         [ +  + ]:         972 :  tetra_shifts(:, 2, 6,4) = [  1,  0,  0]
     534         [ +  + ]:         972 :  tetra_shifts(:, 3, 6,4) = [  0, -1,  1]
     535         [ +  + ]:         972 :  tetra_shifts(:, 4, 6,4) = [  0,  0,  1]
     536         [ +  + ]:         972 :  tetra_shifts(:, 1, 7,4) = [  0,  0,  0]
     537         [ +  + ]:         972 :  tetra_shifts(:, 2, 7,4) = [ -1, -1,  1]
     538         [ +  + ]:         972 :  tetra_shifts(:, 3, 7,4) = [ -1, -1,  0]
     539         [ +  + ]:         972 :  tetra_shifts(:, 4, 7,4) = [  0, -1,  0]
     540         [ +  + ]:         972 :  tetra_shifts(:, 1, 8,4) = [  0,  0,  0]
     541         [ +  + ]:         972 :  tetra_shifts(:, 2, 8,4) = [ -1, -1,  1]
     542         [ +  + ]:         972 :  tetra_shifts(:, 3, 8,4) = [ -1, -1,  0]
     543         [ +  + ]:         972 :  tetra_shifts(:, 4, 8,4) = [ -1,  0,  0]
     544         [ +  + ]:         972 :  tetra_shifts(:, 1, 9,4) = [  0,  0,  0]
     545         [ +  + ]:         972 :  tetra_shifts(:, 2, 9,4) = [ -1, -1,  1]
     546         [ +  + ]:         972 :  tetra_shifts(:, 3, 9,4) = [  0, -1,  1]
     547         [ +  + ]:         972 :  tetra_shifts(:, 4, 9,4) = [  0, -1,  0]
     548         [ +  + ]:         972 :  tetra_shifts(:, 1,10,4) = [  0,  0,  0]
     549         [ +  + ]:         972 :  tetra_shifts(:, 2,10,4) = [ -1, -1,  1]
     550         [ +  + ]:         972 :  tetra_shifts(:, 3,10,4) = [ -1,  0,  1]
     551         [ +  + ]:         972 :  tetra_shifts(:, 4,10,4) = [ -1,  0,  0]
     552         [ +  + ]:         972 :  tetra_shifts(:, 1,11,4) = [  0,  0,  0]
     553         [ +  + ]:         972 :  tetra_shifts(:, 2,11,4) = [ -1, -1,  1]
     554         [ +  + ]:         972 :  tetra_shifts(:, 3,11,4) = [  0, -1,  1]
     555         [ +  + ]:         972 :  tetra_shifts(:, 4,11,4) = [  0,  0,  1]
     556         [ +  + ]:         972 :  tetra_shifts(:, 1,12,4) = [  0,  0,  0]
     557         [ +  + ]:         972 :  tetra_shifts(:, 2,12,4) = [ -1, -1,  1]
     558         [ +  + ]:         972 :  tetra_shifts(:, 3,12,4) = [ -1,  0,  1]
     559         [ +  + ]:         972 :  tetra_shifts(:, 4,12,4) = [  0,  0,  1]
     560         [ +  + ]:         972 :  tetra_shifts(:, 1,13,4) = [  0,  0,  0]
     561         [ +  + ]:         972 :  tetra_shifts(:, 2,13,4) = [  0,  0, -1]
     562         [ +  + ]:         972 :  tetra_shifts(:, 3,13,4) = [  1,  0, -1]
     563         [ +  + ]:         972 :  tetra_shifts(:, 4,13,4) = [  1,  1, -1]
     564         [ +  + ]:         972 :  tetra_shifts(:, 1,14,4) = [  0,  0,  0]
     565         [ +  + ]:         972 :  tetra_shifts(:, 2,14,4) = [  0,  0, -1]
     566         [ +  + ]:         972 :  tetra_shifts(:, 3,14,4) = [  0,  1, -1]
     567         [ +  + ]:         972 :  tetra_shifts(:, 4,14,4) = [  1,  1, -1]
     568         [ +  + ]:         972 :  tetra_shifts(:, 1,15,4) = [  0,  0,  0]
     569         [ +  + ]:         972 :  tetra_shifts(:, 2,15,4) = [  1,  0,  0]
     570         [ +  + ]:         972 :  tetra_shifts(:, 3,15,4) = [  1,  0, -1]
     571         [ +  + ]:         972 :  tetra_shifts(:, 4,15,4) = [  1,  1, -1]
     572         [ +  + ]:         972 :  tetra_shifts(:, 1,16,4) = [  0,  0,  0]
     573         [ +  + ]:         972 :  tetra_shifts(:, 2,16,4) = [  0,  1,  0]
     574         [ +  + ]:         972 :  tetra_shifts(:, 3,16,4) = [  0,  1, -1]
     575         [ +  + ]:         972 :  tetra_shifts(:, 4,16,4) = [  1,  1, -1]
     576         [ +  + ]:         972 :  tetra_shifts(:, 1,17,4) = [  0,  0,  0]
     577         [ +  + ]:         972 :  tetra_shifts(:, 2,17,4) = [  1,  0,  0]
     578         [ +  + ]:         972 :  tetra_shifts(:, 3,17,4) = [  1,  1,  0]
     579         [ +  + ]:         972 :  tetra_shifts(:, 4,17,4) = [  1,  1, -1]
     580         [ +  + ]:         972 :  tetra_shifts(:, 1,18,4) = [  0,  0,  0]
     581         [ +  + ]:         972 :  tetra_shifts(:, 2,18,4) = [  0,  1,  0]
     582         [ +  + ]:         972 :  tetra_shifts(:, 3,18,4) = [  1,  1,  0]
     583         [ +  + ]:         972 :  tetra_shifts(:, 4,18,4) = [  1,  1, -1]
     584         [ +  + ]:         972 :  tetra_shifts(:, 1,19,4) = [  0,  0,  0]
     585         [ +  + ]:         972 :  tetra_shifts(:, 2,19,4) = [  0,  0, -1]
     586         [ +  + ]:         972 :  tetra_shifts(:, 3,19,4) = [  0,  1, -1]
     587         [ +  + ]:         972 :  tetra_shifts(:, 4,19,4) = [ -1,  0,  0]
     588         [ +  + ]:         972 :  tetra_shifts(:, 1,20,4) = [  0,  0,  0]
     589         [ +  + ]:         972 :  tetra_shifts(:, 2,20,4) = [  0,  1,  0]
     590         [ +  + ]:         972 :  tetra_shifts(:, 3,20,4) = [  0,  1, -1]
     591         [ +  + ]:         972 :  tetra_shifts(:, 4,20,4) = [ -1,  0,  0]
     592         [ +  + ]:         972 :  tetra_shifts(:, 1,21,4) = [  0,  0,  0]
     593         [ +  + ]:         972 :  tetra_shifts(:, 2,21,4) = [  0,  0, -1]
     594         [ +  + ]:         972 :  tetra_shifts(:, 3,21,4) = [  1,  0, -1]
     595         [ +  + ]:         972 :  tetra_shifts(:, 4,21,4) = [  0, -1,  0]
     596         [ +  + ]:         972 :  tetra_shifts(:, 1,22,4) = [  0,  0,  0]
     597         [ +  + ]:         972 :  tetra_shifts(:, 2,22,4) = [  1,  0,  0]
     598         [ +  + ]:         972 :  tetra_shifts(:, 3,22,4) = [  1,  0, -1]
     599         [ +  + ]:         972 :  tetra_shifts(:, 4,22,4) = [  0, -1,  0]
     600         [ +  + ]:         972 :  tetra_shifts(:, 1,23,4) = [  0,  0,  0]
     601         [ +  + ]:         972 :  tetra_shifts(:, 2,23,4) = [  0,  0, -1]
     602         [ +  + ]:         972 :  tetra_shifts(:, 3,23,4) = [ -1, -1,  0]
     603         [ +  + ]:         972 :  tetra_shifts(:, 4,23,4) = [  0, -1,  0]
     604         [ +  + ]:         972 :  tetra_shifts(:, 1,24,4) = [  0,  0,  0]
     605         [ +  + ]:         972 :  tetra_shifts(:, 2,24,4) = [  0,  0, -1]
     606         [ +  + ]:         972 :  tetra_shifts(:, 3,24,4) = [ -1, -1,  0]
     607         [ +  + ]:         972 :  tetra_shifts(:, 4,24,4) = [ -1,  0,  0]
     608                 :             : 
     609                 :             :  ! These shifts are taken from previous tetrahedron implementation by MJV and BXU
     610                 :             :  ! TODO: implement shifts for the other diagonals
     611         [ +  + ]:         972 :  tetra_shifts_6(:,1,1,1) = [0,0,0]
     612         [ +  + ]:         972 :  tetra_shifts_6(:,2,1,1) = [1,0,0]
     613         [ +  + ]:         972 :  tetra_shifts_6(:,3,1,1) = [0,1,0]
     614         [ +  + ]:         972 :  tetra_shifts_6(:,4,1,1) = [1,0,1]
     615         [ +  + ]:         972 :  tetra_shifts_6(:,1,2,1) = [1,0,0]
     616         [ +  + ]:         972 :  tetra_shifts_6(:,2,2,1) = [1,1,0]
     617         [ +  + ]:         972 :  tetra_shifts_6(:,3,2,1) = [0,1,0]
     618         [ +  + ]:         972 :  tetra_shifts_6(:,4,2,1) = [1,0,1]
     619         [ +  + ]:         972 :  tetra_shifts_6(:,1,3,1) = [0,1,0]
     620         [ +  + ]:         972 :  tetra_shifts_6(:,2,3,1) = [1,1,0]
     621         [ +  + ]:         972 :  tetra_shifts_6(:,3,3,1) = [1,0,1]
     622         [ +  + ]:         972 :  tetra_shifts_6(:,4,3,1) = [1,1,1]
     623         [ +  + ]:         972 :  tetra_shifts_6(:,1,4,1) = [0,0,0]
     624         [ +  + ]:         972 :  tetra_shifts_6(:,2,4,1) = [0,1,0]
     625         [ +  + ]:         972 :  tetra_shifts_6(:,3,4,1) = [0,0,1]
     626         [ +  + ]:         972 :  tetra_shifts_6(:,4,4,1) = [1,0,1]
     627         [ +  + ]:         972 :  tetra_shifts_6(:,1,5,1) = [0,0,1]
     628         [ +  + ]:         972 :  tetra_shifts_6(:,2,5,1) = [1,0,1]
     629         [ +  + ]:         972 :  tetra_shifts_6(:,3,5,1) = [0,1,0]
     630         [ +  + ]:         972 :  tetra_shifts_6(:,4,5,1) = [0,1,1]
     631         [ +  + ]:         972 :  tetra_shifts_6(:,1,6,1) = [0,1,0]
     632         [ +  + ]:         972 :  tetra_shifts_6(:,2,6,1) = [1,0,1]
     633         [ +  + ]:         972 :  tetra_shifts_6(:,3,6,1) = [0,1,1]
     634         [ +  + ]:         972 :  tetra_shifts_6(:,4,6,1) = [1,1,1]
     635                 :             : 
     636         [ +  + ]:         972 :  main_diagonals(:,1) = [ 1, 1, 1] ! 0-7
     637         [ +  + ]:         972 :  main_diagonals(:,2) = [-1, 1, 1] ! 1-6
     638         [ +  + ]:         972 :  main_diagonals(:,3) = [ 1,-1, 1] ! 2-5
     639         [ +  + ]:         972 :  main_diagonals(:,4) = [ 1, 1,-1] ! 3-4
     640                 :             : 
     641                 :         243 :  nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
     642                 :         243 :  tetra%nkibz = nkpt_ibz
     643                 :         243 :  tetra%nkbz = nkpt_fullbz
     644                 :             :  ! HM: this value should be important for performance
     645                 :             :  ! more buckets means faster queries for unique tetrahedra
     646                 :             :  ! but more memory due to the initial size TETRA_SIZE of the buckets
     647                 :             :  ! when changing the number of buckets one should also change the hash function
     648                 :             :  ! to distribute the tetrahedra in the buckets as uniformly as possible
     649                 :             :  ! the simplest hash (not the best!) is:
     650                 :             :  ! ihash = mod(sum(tetra_ibz),nbuckts)
     651                 :             :  ! the value of sum(tetra_ibz) is between 1 and 4*nkibz so I use nkibz nbuckets
     652                 :             :  ! a larger number of buckets should speed up finding the irreducible tetrahedra
     653                 :             :  ! but with more memory allocated
     654                 :         243 :  tetra%nbuckets = nkpt_ibz
     655                 :         243 :  ierr = 0
     656   [ -  +  +  -  :      225265 :  ABI_CALLOC(tetra_hash_count,(tetra%nbuckets))
          +  -  +  -  -  
             +  -  +  +  
                      + ]
     657                 :             : 
     658                 :             :  ! Determine the smallest diagonal in k-space
     659                 :             :  min_length = huge(min_length)
     660         [ +  + ]:        1215 :  do idiag = 1,4
     661                 :             :    diag(:) = gprimd(:,1)*main_diagonals(1,idiag)+&
     662                 :             :              gprimd(:,2)*main_diagonals(2,idiag)+&
     663         [ +  + ]:        3888 :              gprimd(:,3)*main_diagonals(3,idiag)
     664                 :         972 :    length = sqrt(diag(1)*diag(1) + diag(2)*diag(2) + diag(3)*diag(3))
     665         [ +  + ]:        1215 :    if (length < min_length) then
     666                 :         246 :      min_length = length
     667                 :         246 :      min_idiag = idiag
     668                 :             :    end if
     669                 :             :  end do
     670                 :             : 
     671                 :             :  ! HM TODO: Avoid krank and map the k-point grid to indexes
     672                 :             :  ! Make full k-point rank arrays
     673                 :             :  !oct = octree_init(kpt_fullbz,2**4,[-one,-one,-one],[two,two,two])
     674                 :         243 :  call krank%init(nkpt_fullbz, kpt_fullbz)
     675                 :             :  !
     676                 :             :  ! HM (13/04/2019): I implement two different versions:
     677                 :             :  ! 1. I only use 24 tetrahedra around the IBZ k-point
     678                 :             :  ! following the approach of A. Togo (phonopy, spglib, kspclib).
     679                 :             :  ! 2. I generate tetrahedra on the full Brillouin zone
     680                 :             :  ! and keep track of how many are contributing to the IBZ point and the multiplicities,
     681                 :             :  ! these can be more than 24 tetrahedra.
     682                 :             :  ! This is equivalent to what Matthieu implemented but avoids large memory allocations.
     683                 :             :  !
     684                 :             :  ! The two implementations differ specially when using low k-point sampling
     685                 :             :  ! (the second yields the same results using IBZ or FBZ, the first one not).
     686                 :             :  ! For large sampling the two approaches yield similar results, with the first
     687                 :             :  ! one using less memory, faster to generate and compute
     688                 :             :  !
     689   [ -  +  +  -  :      225265 :  ABI_MALLOC(tetra%unique_tetra,(tetra%nbuckets))
          +  -  +  -  -  
          +  -  +  -  +  
                   +  + ]
     690         [ +  + ]:      224779 :  do ihash=1,tetra%nbuckets
     691   [ -  +  -  +  :     8308075 :    ABI_CALLOC(tetra%unique_tetra(ihash)%indexes,(0:4,TETRA_SIZE))
             +  +  +  + ]
     692                 :             :  end do
     693         [ -  + ]:         243 :  tetra%opt = 2; if (present(opt)) tetra%opt = opt
     694                 :             : 
     695                 :         243 :  select case(tetra%opt)
     696                 :             :  case (1)
     697                 :             :    ! For each k-point in the IBZ store 24 tetrahedra each referring to 4 k-points
     698         [ #  # ]:           0 :    do ikibz=1,tetra%nkibz
     699                 :             :      !if (mod(ikibz,nprocs) /= my_rank) cycle
     700         [ #  # ]:           0 :      k1 = kpt_ibz(:,ikibz)
     701         [ #  # ]:           0 :      tetra_loop1: do itetra=1,24
     702         [ #  # ]:           0 :        do isummit=1,4
     703                 :             :          ! Find the index of the neighbouring k-points in the BZ
     704                 :             :          k2 = k1 + tetra_shifts(1,isummit,itetra,min_idiag)*klatt(:,1) + &
     705                 :             :                    tetra_shifts(2,isummit,itetra,min_idiag)*klatt(:,2) + &
     706         [ #  # ]:           0 :                    tetra_shifts(3,isummit,itetra,min_idiag)*klatt(:,3)
     707                 :             :          ! Find full kpoint which is summit isummit of tetrahedron itetra around full kpt ikpt_full !
     708                 :             :          !ikpt2 = octree_find(oct,k2,dist)
     709                 :             :          !ikpt2 = octree_find_nearest_pbc(oct,k2,dist,shift)
     710                 :             :          !if (dist>tol12) call exit(1)
     711                 :           0 :          ikpt2 = krank%get_index(k2)
     712                 :             :          ! Find the index of those points in the BZ and IBZ
     713                 :           0 :          tetra_ibz(isummit) = bz2ibz(ikpt2)
     714                 :             :        end do
     715                 :             :        ! Sort index of irr k-point edges (need this so the comparison works)
     716                 :           0 :        call sort_4tetra_int(tetra_ibz)
     717                 :             : 
     718                 :             :        ! Store only unique tetrahedra
     719                 :             :        ! Compute a very simple hash for each tetrahedron
     720                 :           0 :        ihash = compute_hash(tetra,tetra_ibz) !mod(sum(tetra_ibz),tetra%nbuckets)+1
     721                 :             :        ! Loop over all tetrahedrons that contain this ikibz as first element
     722         [ #  # ]:           0 :        do jtetra=1,tetra_hash_count(ihash)
     723                 :             :          ! if tetrahedron already exists add multiplicity
     724         [ #  # ]:           0 :          if (tetra%unique_tetra(ihash)%indexes(1,jtetra)/=tetra_ibz(1)) cycle
     725         [ #  # ]:           0 :          if (tetra%unique_tetra(ihash)%indexes(2,jtetra)/=tetra_ibz(2)) cycle
     726         [ #  # ]:           0 :          if (tetra%unique_tetra(ihash)%indexes(3,jtetra)/=tetra_ibz(3)) cycle
     727         [ #  # ]:           0 :          if (tetra%unique_tetra(ihash)%indexes(4,jtetra)/=tetra_ibz(4)) cycle
     728                 :           0 :          tetra%unique_tetra(ihash)%indexes(0,jtetra) = tetra%unique_tetra(ihash)%indexes(0,jtetra)+1
     729                 :           0 :          cycle tetra_loop1
     730                 :             :        end do
     731                 :             :        ! Otherwise store new tetrahedron
     732                 :           0 :        tetra_hash_count(ihash) = tetra_hash_count(ihash)+1
     733                 :           0 :        max_ntetra = size(tetra%unique_tetra(ihash)%indexes,2)
     734                 :             :        ! The contents don't fit the array so I have to resize it
     735         [ #  # ]:           0 :        if (tetra_hash_count(ihash)>max_ntetra) then
     736   [ #  #  #  #  :           0 :          ABI_MALLOC(indexes,(0:4,max_ntetra+TETRA_STEP))
          #  #  #  #  #  
             #  #  #  #  
                      # ]
     737   [ #  #  #  # ]:           0 :          indexes(0:4,:max_ntetra) = tetra%unique_tetra(ihash)%indexes
     738   [ #  #  #  # ]:           0 :          indexes(:,max_ntetra+1:) = 0
     739         [ #  # ]:           0 :          ABI_MOVE_ALLOC(indexes,tetra%unique_tetra(ihash)%indexes)
     740                 :             :        end if
     741         [ #  # ]:           0 :        tetra%unique_tetra(ihash)%indexes(1:,tetra_hash_count(ihash)) = tetra_ibz(:)
     742                 :           0 :        tetra%unique_tetra(ihash)%indexes(0, tetra_hash_count(ihash)) = 1
     743                 :             :      end do tetra_loop1
     744                 :             :    end do
     745                 :             :    ! HM: The multiplicity of the tetrahedrons computed so far is wrong because we are using IBZ
     746                 :             :    ! I compute the k-point multiplicity so I can fix this later on
     747                 :             :    ! Only needed in blochl_weights* interface for looping over tetrahedra.
     748                 :             :    ! in the onewk routines the weight is known outside
     749   [ #  #  #  #  :           0 :    ABI_CALLOC(tetra%ibz_multiplicity,(tetra%nkibz))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     750         [ #  # ]:           0 :    do ikbz=1,nkpt_fullbz
     751                 :           0 :      ikibz = bz2ibz(ikbz)
     752                 :           0 :      tetra%ibz_multiplicity(ikibz) = tetra%ibz_multiplicity(ikibz) + 1
     753                 :             :    end do
     754                 :             : 
     755                 :             :  case(2)
     756                 :         243 :    min_idiag = 1
     757                 :             :    ! For each k-point in the BZ generate the 6 tetrahedra that tessellate a microzone
     758         [ +  + ]:     1409584 :    do ikbz=1,tetra%nkbz
     759         [ +  + ]:     5637364 :      k1 = kpt_fullbz(:,ikbz)
     760         [ +  + ]:     9865630 :      tetra_loop2: do itetra=1,6
     761                 :             :        ! Determine tetrahedron
     762         [ +  + ]:    42280230 :        do isummit=1,4
     763                 :             :          ! Find the index of the neighbouring k-points in the BZ
     764                 :             :          k2 = k1 + tetra_shifts_6(1,isummit,itetra,min_idiag)*klatt(:,1) + &
     765                 :             :                    tetra_shifts_6(2,isummit,itetra,min_idiag)*klatt(:,2) + &
     766         [ +  + ]:   135296736 :                    tetra_shifts_6(3,isummit,itetra,min_idiag)*klatt(:,3)
     767                 :             :          ! Find full kpoint which is summit isummit of tetrahedron itetra around full kpt ikpt_full !
     768                 :             :          !ikpt2 = octree_find(oct,k2,dist)
     769                 :             :          !ikpt2 = octree_find_nearest_pbc(oct,k2,dist,shift)
     770                 :             :          !if (dist>tol12) call exit(1)
     771                 :    33824184 :          ikpt2 = krank%get_index(k2)
     772                 :             :          ! Find the index of those points in the BZ and IBZ
     773                 :    42280230 :          tetra_ibz(isummit) = bz2ibz(ikpt2)
     774                 :             :        end do
     775                 :             :        ! Sort index of irr k-point edges (need this so the comparison works)
     776                 :     8456046 :        call sort_4tetra_int(tetra_ibz)
     777                 :             : 
     778                 :             :        ! Store only unique tetrahedra
     779                 :             :        ! Compute a very simple hash for each tetrahedron
     780                 :     8456046 :        ihash = compute_hash(tetra,tetra_ibz) !mod(sum(tetra_ibz),tetra%nbuckets)+1
     781                 :             :        ! Loop over all tetrahedrons that contain this ikibz as first element
     782         [ +  + ]:   156269209 :        do jtetra=1,tetra_hash_count(ihash)
     783                 :             :          ! if tetrahedron already exists add multiplicity
     784         [ +  + ]:   151530110 :          if (tetra%unique_tetra(ihash)%indexes(1,jtetra)/=tetra_ibz(1)) cycle
     785         [ +  + ]:     4805680 :          if (tetra%unique_tetra(ihash)%indexes(2,jtetra)/=tetra_ibz(2)) cycle
     786         [ +  + ]:     3930585 :          if (tetra%unique_tetra(ihash)%indexes(3,jtetra)/=tetra_ibz(3)) cycle
     787         [ -  + ]:     3716947 :          if (tetra%unique_tetra(ihash)%indexes(4,jtetra)/=tetra_ibz(4)) cycle
     788                 :     3716947 :          tetra%unique_tetra(ihash)%indexes(0,jtetra) = tetra%unique_tetra(ihash)%indexes(0,jtetra)+1
     789                 :   156269209 :          cycle tetra_loop2
     790                 :             :        end do
     791                 :             :        ! Otherwise store new tetrahedron
     792                 :     4739099 :        tetra_hash_count(ihash) = tetra_hash_count(ihash)+1
     793                 :     4739099 :        max_ntetra = size(tetra%unique_tetra(ihash)%indexes,2)
     794                 :             :        ! The contents don't fit the array so I have to resize it
     795         [ +  + ]:     4739099 :        if (tetra_hash_count(ihash)>max_ntetra) then
     796   [ +  -  -  +  :     1975152 :          ABI_MALLOC(indexes,(0:4,max_ntetra+TETRA_STEP))
          +  -  +  -  +  
             -  -  +  -  
                      + ]
     797   [ +  +  +  + ]:    71822824 :          indexes(0:4,:max_ntetra) = tetra%unique_tetra(ihash)%indexes
     798   [ +  +  +  + ]:    24360208 :          indexes(:,max_ntetra+1:) = 0
     799         [ +  - ]:      658384 :          ABI_MOVE_ALLOC(indexes,tetra%unique_tetra(ihash)%indexes)
     800                 :             :        end if
     801         [ +  + ]:    23695495 :        tetra%unique_tetra(ihash)%indexes(1:,tetra_hash_count(ihash)) = tetra_ibz(:)
     802                 :     6148440 :        tetra%unique_tetra(ihash)%indexes(0, tetra_hash_count(ihash)) = 1
     803                 :             :      end do tetra_loop2
     804                 :             :    end do
     805                 :             :  case default
     806                 :           0 :    ierr = 1
     807                 :           0 :    write(errorstring,*) 'Invalid option for the generation of tetrahedra,',ch10,&
     808                 :           0 :                         'possible options are:',ch10,&
     809                 :           0 :                         '1. Generate 24 tetrahedra per k-point',ch10,&
     810                 :           0 :                         '2. Generate tetrahedra in the FBZ a map to IBZ (default)'
     811      [ -  +  - ]:         243 :    return
     812                 :             :  end select
     813                 :             : 
     814                 :             :  !ierr = octree_free(oct)
     815         [ -  + ]:         243 :  ABI_FREE(tetra_hash_count)
     816                 :         243 :  call krank%free()
     817                 :             : 
     818                 :             :  ! Do some maintenance: free unused memory and count unique tetrahedra per IBZ point
     819                 :         243 :  tetra%nunique_tetra = 0
     820         [ +  + ]:      224779 :  do ihash=1,tetra%nbuckets
     821                 :             :    ! Count tetrahedra in this bucket
     822   [ +  +  +  + ]:     5522056 :    ntetra = count(tetra%unique_tetra(ihash)%indexes(0,:)>0)
     823                 :      224536 :    tetra%nunique_tetra = tetra%nunique_tetra + ntetra
     824                 :             :    ! Allocate array with right size
     825   [ +  +  +  -  :      673608 :    ABI_MALLOC(indexes,(0:4,ntetra))
          +  -  +  +  -  
                +  -  + ]
     826   [ +  -  +  -  :    28883666 :    indexes = tetra%unique_tetra(ihash)%indexes(:,:ntetra)
          -  +  -  -  +  
                +  +  + ]
     827         [ +  - ]:      224779 :    ABI_MOVE_ALLOC(indexes, tetra%unique_tetra(ihash)%indexes)
     828                 :             :  end do
     829                 :             : 
     830                 :             :  ! Sum the multiplicity
     831   [ -  +  +  -  :         729 :  ABI_MALLOC(tetra%tetra_count,(tetra%nkibz))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     832   [ -  +  +  -  :         729 :  ABI_MALLOC(tetra%tetra_total,(tetra%nkibz))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     833         [ +  + ]:      224779 :  tetra%tetra_count = 0
     834         [ +  + ]:      224779 :  tetra%tetra_total = 0
     835         [ +  + ]:      224779 :  do ihash=1,tetra%nbuckets
     836                 :      224536 :    ntetra = size(tetra%unique_tetra(ihash)%indexes,2)
     837         [ +  + ]:     4963878 :    do itetra=1,ntetra
     838         [ +  + ]:    28434594 :      tetra_mibz = tetra%unique_tetra(ihash)%indexes(:,itetra)
     839         [ +  + ]:    23920031 :      do isummit=1,4
     840                 :    18956396 :        ikibz = tetra_mibz(isummit)
     841                 :    18956396 :        tetra%tetra_total(ikibz) = tetra%tetra_total(ikibz) + tetra_mibz(0)
     842                 :    23695495 :        tetra%tetra_count(ikibz) = tetra%tetra_count(ikibz) + 1
     843                 :             :      end do
     844                 :             :    end do
     845                 :             :  end do
     846         [ +  + ]:      224779 :  tetra%nibz_tetra = sum(tetra%tetra_count)
     847                 :             : 
     848                 :             :  ! HM: This was being allocated here, however this is only used when we loop over kpoints
     849                 :             :  ! I will only allocate this memory if the htetra_get_onewk_* routines are called (lazy evaluation)
     850                 :             :  !call htetra_init_mapping_ibz(tetra)
     851                 :             : 
     852                 :             :  ! Calculate the volume of the tetrahedra
     853                 :             :  rcvol = abs(gprimd(1,1)*(gprimd(2,2)*gprimd(3,3)-gprimd(3,2)*gprimd(2,3))- &
     854                 :             :              gprimd(2,1)*(gprimd(1,2)*gprimd(3,3)-gprimd(3,2)*gprimd(1,3))+ &
     855                 :         243 :              gprimd(3,1)*(gprimd(1,2)*gprimd(2,3)-gprimd(2,2)*gprimd(1,3)))
     856                 :             : 
     857                 :             :  ! Volume of all tetrahedra should be the same as that of tetra 1
     858                 :             :  ! this is the volume of 1 tetrahedron, should be coherent with notation in Lehmann & Taut
     859         [ +  + ]:         972 :  k1(:) = gprimd(:,1)*klatt(1,1) + gprimd(:,2)*klatt(2,1) + gprimd(:,3)*klatt(3,1)
     860         [ +  + ]:         972 :  k2(:) = gprimd(:,1)*klatt(1,2) + gprimd(:,2)*klatt(2,2) + gprimd(:,3)*klatt(3,2)
     861         [ +  + ]:         972 :  k3(:) = gprimd(:,1)*klatt(1,3) + gprimd(:,2)*klatt(2,3) + gprimd(:,3)*klatt(3,3)
     862                 :             :  tetra%vv = abs(k1(1)*(k2(2)*k3(3)-k2(3)*k3(2))- &
     863                 :             :                 k1(2)*(k2(1)*k3(3)-k2(3)*k3(1))+ &
     864   [ -  -  -  +  :         243 :                 k1(3)*(k2(1)*k3(2)-k2(2)*k3(1))) / 6.d0 / rcvol
          -  +  -  +  -  
             -  -  -  -  
                      - ]
     865                 :             : 
     866                 :             :  contains
     867                 :     8456046 :  integer function compute_hash(tetra,t) result(ihash)
     868                 :             :    class(htetra_t),intent(in) :: tetra
     869                 :             :    integer,intent(in) :: t(4)
     870   [ -  -  +  + ]:    42280230 :    ihash = mod(sum(t), tetra%nbuckets) + 1
     871                 :             :    ! TODO: should use a more general hash function that supports more buckets
     872                 :             :    ! Something like:
     873                 :             :    ! id = t(1)*nk3+t(2)*nk2+t(3)*nk1+t(4)
     874                 :             :    ! where nk is the number of points in the IBZ
     875                 :             :    ! Computing this leads to overflow so should use
     876                 :             :    ! mod computation operations
     877                 :             :    ! (A + B) mod C = (A mod C + B mod C) mod C
     878                 :             :    ! (A * B) mod C = (A mod C * B mod C) mod C
     879                 :             :    ! A^B mod C = ( (A mod C)^B ) mod C
     880                 :             :  end function compute_hash
     881                 :             : 
     882                 :             : end subroutine htetra_init
     883                 :             : !!***
     884                 :             : 
     885                 :             : !----------------------------------------------------------------------
     886                 :             : 
     887                 :             : !!****f* m_htetra/htetra_init_mapping_ibz
     888                 :             : !! NAME
     889                 :             : !! htetra_init_mapping_ibz
     890                 :             : !!
     891                 :             : !! FUNCTION
     892                 :             : !!  The mapping to the IBZ has its own allocation routine.
     893                 :             : !!  I will only allocate this memory if the htetra_get_onewk_* routines are called (lazy evaluation)
     894                 :             : !!
     895                 :             : !! SOURCE
     896                 :             : 
     897                 :         157 : subroutine htetra_init_mapping_ibz(tetra)
     898                 :             : 
     899                 :             :  class(htetra_t),intent(inout) :: tetra
     900                 :             : 
     901                 :             :  integer :: ikibz, itetra, isummit, ihash, ntetra
     902                 :         157 :  integer :: tetra_count(tetra%nkibz),tetra_mibz(0:4)
     903                 :             :  real(dp) :: mem_mb
     904                 :             : 
     905                 :             :  ! Only execute the following if not yet allocated
     906         [ -  + ]:         157 :  if (allocated(tetra%ibz)) return
     907                 :             : 
     908                 :             :  ! Allocate IBZ to tetrahedron mapping
     909   [ -  +  +  -  :       21562 :  ABI_MALLOC(tetra%ibz, (tetra%nkibz))
          +  -  +  -  -  
          +  -  +  -  +  
                   +  + ]
     910         [ +  + ]:         314 :  mem_mb = ABI_MEM_MB(tetra%ibz)
     911         [ +  + ]:       21248 :  do ikibz=1,tetra%nkibz
     912   [ -  +  +  -  :       63273 :    ABI_MALLOC(tetra%ibz(ikibz)%indexes, (2, tetra%tetra_count(ikibz)))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     913                 :       21248 :    mem_mb = mem_mb + 2 * tetra%tetra_count(ikibz) * 4 * b2Mb
     914                 :             :  end do
     915                 :             : 
     916                 :         157 :  call wrtout(std_out, sjoin(" Allocating tetra%ibz%indexes with memory:", ftoa(mem_mb, fmt="f8.1"), " [Mb] <<< MEM"))
     917                 :             : 
     918                 :             :  ! Create mapping from IBZ to unique tetrahedra
     919         [ +  + ]:       21248 :  tetra_count = 0
     920         [ +  + ]:       21248 :  do ihash=1,tetra%nbuckets
     921                 :       21091 :    ntetra = size(tetra%unique_tetra(ihash)%indexes, dim=2)
     922         [ +  + ]:      869866 :    do itetra=1,ntetra
     923         [ +  + ]:     5091708 :      tetra_mibz = tetra%unique_tetra(ihash)%indexes(:,itetra)
     924         [ +  + ]:     4264181 :      do isummit=1,4
     925                 :     3394472 :        ikibz = tetra_mibz(isummit)
     926                 :     3394472 :        tetra_count(ikibz) = tetra_count(ikibz) + 1
     927                 :     3394472 :        tetra%ibz(ikibz)%indexes(1, tetra_count(ikibz)) = ihash
     928                 :     4243090 :        tetra%ibz(ikibz)%indexes(2, tetra_count(ikibz)) = itetra
     929                 :             :      end do
     930                 :             :    end do
     931                 :             :  end do
     932                 :             : 
     933                 :             : end subroutine htetra_init_mapping_ibz
     934                 :             : !!***
     935                 :             : 
     936                 :             : !----------------------------------------------------------------------
     937                 :             : 
     938                 :             : !!****f* m_htetra/htetra_get_ibz
     939                 :             : !! NAME
     940                 :             : !! htetra_get_ibz
     941                 :             : !!
     942                 :             : !! FUNCTION
     943                 :             : !!  Get the itetra tetrahedron contributing to the ikibz k-point
     944                 :             : !!
     945                 :             : !! SOURCE
     946                 :             : 
     947                 :    15710160 : pure subroutine htetra_get_ibz(tetra, ikibz, itetra, tetra_mibz)
     948                 :             : 
     949                 :             :  class(htetra_t), intent(in) :: tetra
     950                 :             :  integer,intent(in) :: ikibz, itetra
     951                 :             :  integer,intent(out) :: tetra_mibz(0:4)
     952                 :             :  integer :: ihash, jtetra
     953                 :             : 
     954                 :    15710160 :  ihash  = tetra%ibz(ikibz)%indexes(1,itetra)
     955                 :    15710160 :  jtetra = tetra%ibz(ikibz)%indexes(2,itetra)
     956         [ +  + ]:    94260960 :  tetra_mibz = tetra%unique_tetra(ihash)%indexes(:,jtetra)
     957                 :             : 
     958                 :    15710160 : end subroutine htetra_get_ibz
     959                 :             : !!***
     960                 :             : 
     961                 :             : !----------------------------------------------------------------------
     962                 :             : 
     963                 :             : !!****f* m_htetra/htetra_print
     964                 :             : !! NAME
     965                 :             : !! htetra_print
     966                 :             : !!
     967                 :             : !! FUNCTION
     968                 :             : !!  write information about the tetrahedra object
     969                 :             : !!
     970                 :             : !! SOURCE
     971                 :             : 
     972                 :          62 : subroutine htetra_print(self, unit)
     973                 :             : 
     974                 :             :  class(htetra_t), intent(in) :: self
     975                 :             :  integer,intent(in) :: unit
     976                 :             : 
     977                 :             :  real(dp) :: total_size, unique_tetra_size, ibz_pointer_size
     978                 :             : 
     979         [ -  + ]:          62 :  if (unit == dev_null) return
     980                 :             : 
     981                 :          62 :  unique_tetra_size = self%nunique_tetra * 5* four / 1024 ** 2
     982                 :          62 :  total_size        = unique_tetra_size
     983                 :             :  !write(unit,'(a,i0)')     ' htetra unique_tetra:', self%nunique_tetra
     984                 :             :  !write(unit,'(a,f12.1,a)') ' htetra unique_tetra_size ', unique_tetra_size, ' [Mb] <<< MEM'
     985         [ -  + ]:          62 :  if (allocated(self%ibz)) then
     986                 :           0 :    ibz_pointer_size  = self%nibz_tetra*2*four / 1024 ** 2
     987                 :           0 :    write(unit,'(a,i0)')     ' ibz_tetra: ', self%nibz_tetra
     988                 :           0 :    write(unit,'(a,f12.1,a)') ' ibz_tetra_size: ', ibz_pointer_size, ' [Mb] <<< MEM'
     989                 :           0 :    total_size = total_size + ibz_pointer_size
     990                 :             :  end if
     991                 :             :  ! integer arrays
     992                 :          62 :  total_size = total_size + 3 * (self%nkibz * 4) / 1024**2
     993                 :          62 :  write(unit,'(a,f12.1,a)') ' htetra total size:', total_size, ' [Mb] <<< MEM'
     994                 :             : 
     995                 :             : end subroutine htetra_print
     996                 :             : !!***
     997                 :             : 
     998                 :             : !----------------------------------------------------------------------
     999                 :             : 
    1000                 :             : !!****f* m_htetra/htetra_free
    1001                 :             : !! NAME
    1002                 :             : !! htetra_free
    1003                 :             : !!
    1004                 :             : !! FUNCTION
    1005                 :             : !! deallocate tetrahedra pointers if needed
    1006                 :             : !!
    1007                 :             : !! SOURCE
    1008                 :             : 
    1009                 :         374 : subroutine htetra_free(tetra)
    1010                 :             : 
    1011                 :             :  class(htetra_t), intent(inout) :: tetra
    1012                 :             :  integer :: ikibz,ihash
    1013                 :             : 
    1014         [ +  + ]:         374 :  ABI_SFREE(tetra%tetra_count)
    1015         [ +  + ]:         374 :  ABI_SFREE(tetra%tetra_total)
    1016         [ -  + ]:         374 :  ABI_SFREE(tetra%ibz_multiplicity)
    1017                 :             : 
    1018         [ +  + ]:         374 :  if (allocated(tetra%unique_tetra)) then
    1019         [ +  + ]:      224779 :    do ihash=1,tetra%nbuckets
    1020         [ +  - ]:      224779 :      ABI_SFREE(tetra%unique_tetra(ihash)%indexes)
    1021                 :             :    end do
    1022   [ +  -  +  +  :      224779 :    ABI_FREE(tetra%unique_tetra)
             -  +  -  + ]
    1023                 :             :  end if
    1024                 :             : 
    1025         [ +  + ]:         374 :  if (allocated(tetra%ibz)) then
    1026         [ +  + ]:       21248 :    do ikibz=1,tetra%nkibz
    1027         [ +  - ]:       21248 :      ABI_SFREE(tetra%ibz(ikibz)%indexes)
    1028                 :             :    end do
    1029   [ +  -  +  +  :       21248 :    ABI_FREE(tetra%ibz)
             -  +  -  + ]
    1030                 :             :  end if
    1031                 :             : 
    1032                 :         374 : end subroutine htetra_free
    1033                 :             : !!***
    1034                 :             : 
    1035                 :             : !----------------------------------------------------------------------
    1036                 :             : 
    1037                 :             : !!****f* m_htetra/get_onetetra_blochl
    1038                 :             : !! NAME
    1039                 :             : !! get_onetetra_blochl
    1040                 :             : !!
    1041                 :             : !! FUNCTION
    1042                 :             : !! Private function to calculate the contributions to the weights due to a single tetrahedron.
    1043                 :             : !! Extracted from get_tetra_weight
    1044                 :             : !!
    1045                 :             : !! SOURCE
    1046                 :             : 
    1047                 :   138582926 : pure subroutine get_onetetra_blochl(eig, energies, nene, bcorr, tweight, dweight)
    1048                 :             : 
    1049                 :             : !Arguments ------------------------------------
    1050                 :             : !scalars
    1051                 :             :  integer,intent(in)   :: nene,bcorr
    1052                 :             : !arrays
    1053                 :             :  real(dp),intent(in)  :: eig(4), energies(nene)
    1054                 :             :  real(dp), intent(out) :: tweight(4, nene), dweight(4, nene)
    1055                 :             : 
    1056                 :             : !Local variables-------------------------------
    1057                 :             :  integer :: ieps
    1058                 :             :  real(dp) :: cc,cc1,cc2,cc3
    1059                 :             :  real(dp) :: dcc1de,dcc2de,dcc3de,dccde,eps
    1060                 :             :  real(dp) :: e21,e31,e32,e41,e42,e43
    1061                 :             :  real(dp) :: inv_e32,inv_e41,inv_e42,inv_e43,inv_e21,inv_e31
    1062                 :             :  real(dp) :: deleps1,deleps2,deleps3,deleps4
    1063                 :             :  real(dp) :: e1,e2,e3,e4
    1064                 :             :  real(dp) :: invepsum, cc_pre, dccde_pre
    1065                 :             :  real(dp) :: cc1_pre, cc2_pre, cc3_pre
    1066                 :             :  real(dp) :: dccde_tmp
    1067                 :             :  real(dp) :: bcorr_fact
    1068                 :             : ! *********************************************************************
    1069                 :             : 
    1070                 :             :  ! This is output
    1071   [ +  +  +  +  : >13491*10^7 :  tweight = zero; dweight = zero
             +  +  +  + ]
    1072                 :             : 
    1073                 :             :  ! all notations are from Blochl PRB 49 16223 [[cite:Bloechl1994a]] Appendix B
    1074                 :   138582926 :  e1 = eig(1)
    1075                 :   138582926 :  e2 = eig(2)
    1076                 :   138582926 :  e3 = eig(3)
    1077                 :   138582926 :  e4 = eig(4)
    1078                 :   138582926 :  e21 = e2-e1
    1079                 :   138582926 :  e31 = e3-e1
    1080                 :   138582926 :  e41 = e4-e1
    1081                 :   138582926 :  e32 = e3-e2
    1082                 :   138582926 :  e42 = e4-e2
    1083                 :   138582926 :  e43 = e4-e3
    1084         [ +  + ]:   138582926 :  inv_e21 = zero; if (e21 > tol14) inv_e21 = 1.d0 / e21
    1085         [ +  + ]:   138582926 :  inv_e31 = zero; if (e31 > tol14) inv_e31 = 1.d0 / e31
    1086         [ +  + ]:   138582926 :  inv_e41 = zero; if (e41 > tol14) inv_e41 = 1.d0 / e41
    1087         [ +  + ]:   138582926 :  inv_e32 = zero; if (e32 > tol14) inv_e32 = 1.d0 / e32
    1088         [ +  + ]:   138582926 :  inv_e42 = zero; if (e42 > tol14) inv_e42 = 1.d0 / e42
    1089         [ +  + ]:   138582926 :  inv_e43 = zero; if (e43 > tol14) inv_e43 = 1.d0 / e43
    1090                 :             : 
    1091         [ +  + ]:  7878293144 :  do ieps=1,nene
    1092                 :  7770985705 :    eps = energies(ieps)
    1093                 :             : 
    1094                 :             :    !
    1095                 :             :    ! eps < e1 nothing to do
    1096                 :             :    !
    1097         [ +  + ]:  7770985705 :    if (eps < e1) cycle
    1098                 :             : 
    1099                 :             :    !
    1100                 :             :    ! e1 < eps < e2
    1101                 :             :    !
    1102         [ +  + ]:   510470751 :    if (eps < e2) then
    1103                 :   172325526 :      deleps1 = eps-e1
    1104                 :   172325526 :      invepsum = inv_e21+inv_e31+inv_e41
    1105                 :             : 
    1106                 :             :      ! Heaviside
    1107                 :   172325526 :      cc = inv_e21*inv_e31*inv_e41*deleps1**3
    1108                 :   172325526 :      tweight(1,ieps) = cc*(4.d0-deleps1*invepsum)
    1109                 :   172325526 :      tweight(2,ieps) = cc*deleps1*inv_e21
    1110                 :   172325526 :      tweight(3,ieps) = cc*deleps1*inv_e31
    1111                 :   172325526 :      tweight(4,ieps) = cc*deleps1*inv_e41
    1112                 :             : 
    1113                 :             :      ! Delta
    1114                 :   172325526 :      dccde_pre = 3.d0*inv_e21*inv_e31*inv_e41
    1115                 :   172325526 :      dccde = dccde_pre*deleps1**2
    1116                 :   172325526 :      dweight(1,ieps) = dccde*(4.d0-deleps1*invepsum)-cc*invepsum
    1117                 :   172325526 :      dweight(2,ieps) = (dccde*deleps1+cc) * inv_e21
    1118                 :   172325526 :      dweight(3,ieps) = (dccde*deleps1+cc) * inv_e31
    1119                 :   172325526 :      dweight(4,ieps) = (dccde*deleps1+cc) * inv_e41
    1120                 :             : 
    1121         [ -  + ]:   172325526 :      if (bcorr == 1) then
    1122                 :             :        ! bxu, correction terms based on Bloechl's paper
    1123                 :           0 :        bcorr_fact = 4.d0/40.d0*dccde_pre*deleps1*deleps1
    1124                 :           0 :        tweight(1,ieps) = tweight(1,ieps) + bcorr_fact*( e21+e31+e41)
    1125                 :           0 :        tweight(2,ieps) = tweight(2,ieps) + bcorr_fact*(-e21+e32+e42)
    1126                 :           0 :        tweight(3,ieps) = tweight(3,ieps) + bcorr_fact*(-e31-e32+e43)
    1127                 :           0 :        tweight(4,ieps) = tweight(4,ieps) + bcorr_fact*(-e41-e42-e43)
    1128                 :             : 
    1129                 :           0 :        bcorr_fact = 8.d0/40.d0*dccde_pre*deleps1
    1130                 :           0 :        dweight(1,ieps) = dweight(1,ieps) + bcorr_fact*( e21+e31+e41)
    1131                 :           0 :        dweight(2,ieps) = dweight(2,ieps) + bcorr_fact*(-e21+e32+e42)
    1132                 :           0 :        dweight(3,ieps) = dweight(3,ieps) + bcorr_fact*(-e31-e32+e43)
    1133                 :           0 :        dweight(4,ieps) = dweight(4,ieps) + bcorr_fact*(-e41-e42-e43)
    1134                 :             :      end if
    1135                 :             : 
    1136                 :             :      cycle
    1137                 :             :    endif
    1138                 :             : 
    1139                 :             :    !
    1140                 :             :    ! e2 < eps < e3
    1141                 :             :    !
    1142         [ +  + ]:   338145225 :    if (eps < e3) then
    1143                 :   144551565 :      deleps1 = eps-e1
    1144                 :   144551565 :      deleps2 = eps-e2
    1145                 :   144551565 :      deleps3 = e3-eps
    1146                 :   144551565 :      deleps4 = e4-eps
    1147                 :   144551565 :      cc1_pre = inv_e31*inv_e41
    1148                 :   144551565 :      cc2_pre = inv_e41*inv_e32*inv_e31
    1149                 :   144551565 :      cc3_pre = inv_e42*inv_e32*inv_e41
    1150                 :             : 
    1151                 :             :      ! Heaviside
    1152                 :   144551565 :      cc1 = cc1_pre*deleps1*deleps1
    1153                 :   144551565 :      cc2 = cc2_pre*deleps1*deleps2*deleps3
    1154                 :   144551565 :      cc3 = cc3_pre*deleps2*deleps2*deleps4
    1155                 :             : 
    1156                 :             :      tweight(1,ieps) = (cc1)+&
    1157                 :             :                        (cc1+cc2)*deleps3*inv_e31+&
    1158                 :   144551565 :                        (cc1+cc2+cc3)*deleps4*inv_e41
    1159                 :             :      tweight(2,ieps) = (cc1+cc2+cc3)+&
    1160                 :             :                        (cc2+cc3)*deleps3*inv_e32+&
    1161                 :   144551565 :                            (cc3)*deleps4*inv_e42
    1162                 :             :      tweight(3,ieps) = (cc1+cc2)*deleps1*inv_e31+&
    1163                 :   144551565 :                        (cc2+cc3)*deleps2*inv_e32
    1164                 :             :      tweight(4,ieps) = (cc1+cc2+cc3)*deleps1*inv_e41+&
    1165                 :   144551565 :                                    (cc3)*deleps2*inv_e42
    1166                 :             : 
    1167                 :             :      ! Delta
    1168                 :   144551565 :      dcc1de = cc1_pre*(2.d0*deleps1)
    1169                 :   144551565 :      dcc2de = cc2_pre*(    -deleps1*deleps2+deleps1*deleps3+deleps2*deleps3)
    1170                 :   144551565 :      dcc3de = cc3_pre*(2.d0*deleps2*deleps4-deleps2*deleps2)
    1171                 :             :      dweight(1,ieps) = dcc1de+&
    1172                 :             :                        ((dcc1de+dcc2de)*deleps3-(cc1+cc2))*inv_e31+&
    1173                 :   144551565 :                        ((dcc1de+dcc2de+dcc3de)*deleps4-(cc1+cc2+cc3))*inv_e41
    1174                 :             :      dweight(2,ieps) = (dcc1de+dcc2de+dcc3de)+&
    1175                 :             :                        ((dcc2de+dcc3de)*deleps3-(cc2+cc3))*inv_e32+&
    1176                 :   144551565 :                                       (dcc3de*deleps4-cc3)*inv_e42
    1177                 :             :      dweight(3,ieps) = ((dcc1de+dcc2de)*deleps1+(cc1+cc2))*inv_e31+&
    1178                 :   144551565 :                        ((dcc2de+dcc3de)*deleps2+(cc2+cc3))*inv_e32
    1179                 :             :      dweight(4,ieps) = ((dcc1de+dcc2de+dcc3de)*deleps1+(cc1+cc2+cc3))*inv_e41+&
    1180                 :   144551565 :                                                         (dcc3de*deleps2+cc3)*inv_e42
    1181                 :             : 
    1182         [ -  + ]:   144551565 :      if (bcorr == 1) then
    1183                 :             :        ! bxu, correction terms based on Bloechl's paper
    1184                 :             :        ! The correction terms may cause the dweight become negative
    1185                 :           0 :        bcorr_fact = 4.d0/40.d0*cc1_pre*(3.d0*e21+6.d0*deleps2-3.d0*(e31+e42)*deleps2*deleps2*inv_e32*inv_e42)
    1186                 :           0 :        tweight(1,ieps) = tweight(1,ieps) + bcorr_fact*( e21+e31+e41)
    1187                 :           0 :        tweight(2,ieps) = tweight(2,ieps) + bcorr_fact*(-e21+e32+e42)
    1188                 :           0 :        tweight(3,ieps) = tweight(3,ieps) + bcorr_fact*(-e31-e32+e43)
    1189                 :           0 :        tweight(4,ieps) = tweight(4,ieps) + bcorr_fact*(-e41-e42-e43)
    1190                 :             : 
    1191                 :           0 :        bcorr_fact = 4.d0/40.d0*cc1_pre*(6.d0-6.d0*(e31+e42)*deleps2*inv_e32*inv_e42)
    1192                 :           0 :        dweight(1,ieps) = dweight(1,ieps) + bcorr_fact*( e21+e31+e41)
    1193                 :           0 :        dweight(2,ieps) = dweight(2,ieps) + bcorr_fact*(-e21+e32+e42)
    1194                 :           0 :        dweight(3,ieps) = dweight(3,ieps) + bcorr_fact*(-e31-e32+e43)
    1195                 :           0 :        dweight(4,ieps) = dweight(4,ieps) + bcorr_fact*(-e41-e42-e43)
    1196                 :             :      end if
    1197                 :             : 
    1198                 :             :      cycle
    1199                 :             :    endif
    1200                 :             : 
    1201                 :             :    !
    1202                 :             :    ! e3 < eps < e4
    1203                 :             :    !
    1204         [ +  + ]:   193593660 :    if (eps < e4) then
    1205                 :   162310083 :      deleps4 = e4-eps
    1206                 :   162310083 :      invepsum = inv_e41+inv_e42+inv_e43
    1207                 :             : 
    1208                 :             :      ! Heaviside
    1209                 :   162310083 :      cc_pre = inv_e41*inv_e42*inv_e43
    1210                 :   162310083 :      cc = cc_pre*deleps4**3
    1211                 :   162310083 :      tweight(1,ieps) = one - deleps4*cc*inv_e41
    1212                 :   162310083 :      tweight(2,ieps) = one - deleps4*cc*inv_e42
    1213                 :   162310083 :      tweight(3,ieps) = one - deleps4*cc*inv_e43
    1214                 :   162310083 :      tweight(4,ieps) = one - cc*(4.d0-deleps4*invepsum)
    1215                 :             : 
    1216                 :             :      ! Delta
    1217                 :   162310083 :      dccde = -3.d0*cc_pre*deleps4**2
    1218                 :   162310083 :      dccde_tmp = dccde*deleps4 - cc
    1219                 :   162310083 :      dweight(1,ieps) = -dccde_tmp * inv_e41
    1220                 :   162310083 :      dweight(2,ieps) = -dccde_tmp * inv_e42
    1221                 :   162310083 :      dweight(3,ieps) = -dccde_tmp * inv_e43
    1222                 :   162310083 :      dweight(4,ieps) = -4.d0*dccde + dccde_tmp*invepsum
    1223                 :             : 
    1224         [ -  + ]:   162310083 :      if (bcorr == 1) then
    1225                 :             :        ! bxu, correction terms based on Bloechl's paper
    1226                 :             :        ! The correction terms may cause the dweight become negative
    1227                 :           0 :        bcorr_fact = 12.d0/40.d0*cc_pre*deleps4*deleps4
    1228                 :           0 :        tweight(1,ieps) = tweight(1,ieps) + bcorr_fact*( e21+e31+e41)
    1229                 :           0 :        tweight(2,ieps) = tweight(2,ieps) + bcorr_fact*(-e21+e32+e42)
    1230                 :           0 :        tweight(3,ieps) = tweight(3,ieps) + bcorr_fact*(-e31-e32+e43)
    1231                 :           0 :        tweight(4,ieps) = tweight(4,ieps) + bcorr_fact*(-e41-e42-e43)
    1232                 :             : 
    1233                 :           0 :        bcorr_fact = - 24.d0/40.d0*cc_pre*deleps4
    1234                 :           0 :        dweight(1,ieps) = dweight(1,ieps) + bcorr_fact*( e21+e31+e41)
    1235                 :           0 :        dweight(2,ieps) = dweight(2,ieps) + bcorr_fact*(-e21+e32+e42)
    1236                 :           0 :        dweight(3,ieps) = dweight(3,ieps) + bcorr_fact*(-e31-e32+e43)
    1237                 :           0 :        dweight(4,ieps) = dweight(4,ieps) + bcorr_fact*(-e41-e42-e43)
    1238                 :             :      end if
    1239                 :             : 
    1240                 :             :      cycle
    1241                 :             :    endif
    1242                 :             : 
    1243                 :             :    !
    1244                 :             :    ! e4 < eps
    1245                 :             :    !
    1246         [ +  + ]:   138591016 :    if (e4 < eps) then
    1247                 :             : 
    1248                 :             :      ! Heaviside
    1249   [ +  +  +  + ]: 28719032867 :      tweight(:,ieps:) = one
    1250                 :             : 
    1251                 :             :      ! Delta unchanged by this tetrahedron
    1252                 :             :      exit
    1253                 :             :    end if
    1254                 :             : 
    1255                 :             :    !  if we have a fully degenerate tetrahedron,
    1256                 :             :    !  1) the tweight is a Heaviside (step) function, which is correct above, but
    1257                 :             :    !  2) the dweight should contain a Dirac function
    1258                 :             :    !
    1259                 :             :  end do
    1260                 :             : 
    1261                 :   138582926 : end subroutine get_onetetra_blochl
    1262                 :             : !!***
    1263                 :             : 
    1264                 :             : !!****f* m_htetra/get_onetetra_lambinvigneron
    1265                 :             : !! NAME
    1266                 :             : !! get_onetetra_lambinvigneron
    1267                 :             : !!
    1268                 :             : !! FUNCTION
    1269                 :             : !!  Compute the complex weights according to: P. Lambin and J.P. Vigneron, Phys. Rev. B 29, 3430 (1984)
    1270                 :             : !!  This routine is adapted from tdep where it was implemented
    1271                 :             : !!  by Olle Hellman, all credits go to him
    1272                 :             : !!
    1273                 :             : !! INPUTS
    1274                 :             : !!
    1275                 :             : !! OUTPUT
    1276                 :             : !!
    1277                 :             : !! SOURCE
    1278                 :             : 
    1279                 :             : !pure
    1280                 :           0 : subroutine get_onetetra_lambinvigneron(eig, z, cw)
    1281                 :             : 
    1282                 :             :     ! dispersion values at the corners of the tetrahedron
    1283                 :             :     real(dp), intent(in) :: eig(4)
    1284                 :             :     ! energy to evaluate the weights at
    1285                 :             :     complex(dp), intent(in) :: z
    1286                 :             :     ! complex weights
    1287                 :             :     complex(dp), intent(out) :: cw(4)
    1288                 :             :     complex(dp) :: EZ1,EZ2,EZ3,EZ4
    1289                 :             :     real(dp) :: tol = tol14
    1290                 :             :     !real(dp) :: tol = tol10
    1291                 :             :     !real(dp) :: tol = tol6
    1292                 :             :     real(dp) :: Emin,Emax,Zdist
    1293                 :             :     real(dp) :: E12,E13,E14,E23,E24,E34
    1294                 :             :     real(dp) :: a,b,c,d,e,f
    1295                 :             :     complex(dp) zmE(4), verli(4) !, verm(4)
    1296                 :             :     !integer :: ii, jj
    1297                 :             : 
    1298                 :           0 :     cw = zero
    1299                 :             : 
    1300                 :             :     ! Min and max energy
    1301                 :           0 :     Emin=eig(1)
    1302                 :           0 :     Emax=eig(4)
    1303                 :             : 
    1304                 :             :     ! First the complex energy differences
    1305                 :           0 :     zmE = z - eig(:)
    1306                 :           0 :     EZ1=z-eig(1)
    1307                 :           0 :     EZ2=z-eig(2)
    1308                 :           0 :     EZ3=z-eig(3)
    1309                 :           0 :     EZ4=z-eig(4)
    1310                 :             :     ! Smallest distance |z-Ei|, to determine whether I should switch to the
    1311                 :             :     ! asymptotic behavior for numerical stability.
    1312                 :             :     Zdist=huge(Zdist)
    1313                 :             :     Zdist=min(Zdist,abs(EZ2))
    1314                 :             :     Zdist=min(Zdist,abs(EZ3))
    1315                 :             :     Zdist=min(Zdist,abs(EZ4))
    1316                 :             :     !@TODO add asymptotic thing with continued fractions
    1317                 :             : 
    1318                 :             :     ! Then the energy differences, for the coefficients. Must always be positive, I hope.
    1319                 :           0 :     E12=eig(2)-eig(1)
    1320                 :           0 :     E13=eig(3)-eig(1)
    1321                 :           0 :     E14=eig(4)-eig(1)
    1322                 :           0 :     E23=eig(3)-eig(2)
    1323                 :           0 :     E24=eig(4)-eig(2)
    1324                 :           0 :     E34=eig(4)-eig(3)
    1325                 :           0 :     a=zero; if ( E12 .gt. tol ) a=one/E12
    1326                 :           0 :     b=zero; if ( E13 .gt. tol ) b=one/E13
    1327                 :           0 :     c=zero; if ( E14 .gt. tol ) c=one/E14
    1328                 :           0 :     d=zero; if ( E23 .gt. tol ) d=one/E23
    1329                 :           0 :     e=zero; if ( E24 .gt. tol ) e=one/E24
    1330                 :           0 :     f=zero; if ( E34 .gt. tol ) f=one/E34
    1331                 :             : 
    1332                 :             :     ! Now get the actual weights
    1333                 :             :     ! e1=e2=e3=e4
    1334         [ #  # ]:           0 :     if ( E12+E23+E34 .lt. tol ) then
    1335                 :             : #if 0
    1336                 :             :         !print *, "e1=e2=e3=e4"
    1337                 :             :         cw(1)=0.25_dp/EZ1
    1338                 :             :         cw(2)=0.25_dp/EZ2
    1339                 :             :         cw(3)=0.25_dp/EZ3
    1340                 :             :         cw(4)=0.25_dp/EZ4
    1341                 :             : #else
    1342         [ #  # ]:           0 :         call SIM0TWOI(cw, VERLI, z-eig)
    1343                 :             : #endif
    1344                 :             :     !    e2=e3=e4  ! diff wrt simteta
    1345         [ #  # ]:           0 :     elseif ( E23+E34 .lt. tol ) then
    1346                 :             : #if 0
    1347                 :             :         !print *, "e2=e3=e4"
    1348                 :             :         cw(1)=-a - (3*a**2*EZ2)*half + 3*a**3*EZ1*EZ2 + 3*a**4*EZ1**2*EZ2*Log(EZ2/EZ1)
    1349                 :             :         cw(2)=-a - (3*a**2*EZ2)*half + 3*a**3*EZ1*EZ2 + 3*a**4*EZ1**2*EZ2*Log(EZ2/EZ1)
    1350                 :             :         cw(3)=-a - (3*a**2*EZ2)*half + 3*a**3*EZ1*EZ2 + 3*a**4*EZ1**2*EZ2*Log(EZ2/EZ1)
    1351                 :             :         cw(4)=-a*third + (a**2*EZ1)*half - a**3*EZ1**2 + a**4*EZ1**3*Log(EZ2/EZ1)
    1352                 :             : #else
    1353         [ #  # ]:           0 :         call SIM0TWOI(cw, VERLI, z-eig)
    1354                 :             : #endif
    1355                 :             : 
    1356                 :             :     ! e1=e2=e3
    1357         [ #  # ]:           0 :     elseif ( E12+E23 .lt. tol ) then
    1358                 :             : #if 0
    1359                 :             :         !print *, "e1=e2=e3" ! diff wrt simteta
    1360                 :             :         cw(1)=f*third - (EZ4*f**2)*half + EZ4**2*f**3 + EZ4**3*f**4*Log(EZ4/EZ3)
    1361                 :             :         cw(2)=f*third - (EZ4*f**2)*half + EZ4**2*f**3 + EZ4**3*f**4*Log(EZ4/EZ3)
    1362                 :             :         cw(3)=f*third - (EZ4*f**2)*half + EZ4**2*f**3 + EZ4**3*f**4*Log(EZ4/EZ3)
    1363                 :             :         cw(4)=-f + (3*EZ3*f**2)*half - 3*EZ3*EZ4*f**3 + 3*EZ3*EZ4**2*f**4*Log(EZ3/EZ4)
    1364                 :             : #else
    1365         [ #  # ]:           0 :         call SIM0TWOI(cw, VERLI, z-eig)
    1366                 :             : #endif
    1367                 :             :     ! e1=e2 e3=e4
    1368         [ #  # ]:           0 :     elseif ( E12+E34 .lt. tol ) then
    1369                 :             : #if 0
    1370                 :             :         !print *, "e1=e2 e3=e4"    ! FIXME This is Buggy, does not work even with parabolic dispersion
    1371                 :             :         cw(1)=-d - (3*d**2*EZ2)*half + 3*d**3*EZ2*EZ3 + 3*d**4*EZ2*EZ3**2*Log(EZ2/EZ3)
    1372                 :             :         cw(2)=-d - (3*d**2*EZ2)*half + 3*d**3*EZ2*EZ3 + 3*d**4*EZ2*EZ3**2*Log(EZ2/EZ3)
    1373                 :             :         cw(3)=d - (3*d**2*EZ3)*half - 3*d**3*EZ2*EZ3 + 3*d**4*EZ2**2*EZ3*Log(EZ3/EZ2)
    1374                 :             :         cw(4)=d - (3*d**2*EZ3)*half - 3*d**3*EZ2*EZ3 + 3*d**4*EZ2**2*EZ3*Log(EZ3/EZ2)
    1375                 :             : #else
    1376                 :             :         !cw(1) = nine * EZ3**2 * EZ2 / E23**4 * log(EZ2/EZ3) * EZ2 * (EZ3 -E23)/E23**3 - one/E23
    1377                 :             :         !cw(2) = cw(1)
    1378                 :             :         !cw(3) = nine * EZ2**2 * EZ3 / E23**4 * log(EZ3/EZ2) * EZ3 * (EZ2 +E23)/E23**3 + one/E23
    1379                 :             :         !cw(4) = cw(3)
    1380         [ #  # ]:           0 :         call SIM0TWOI(cw, VERLI, z-eig)
    1381                 :             :         !cw = zero
    1382                 :             : #endif
    1383                 :             : 
    1384                 :             :     !       e3=e4
    1385         [ #  # ]:           0 :     elseif ( E34 .lt. tol ) then
    1386                 :             :         !print *, "e3=e4"
    1387                 :             : #if 0
    1388                 :             :         cw(1)=-(a*b**2*EZ1**2*(-1 + (a*EZ2 + 2*b*EZ3)*Log(EZ1))) + a**2*d**2*EZ2**3*Log(EZ2) - &
    1389                 :             :                 b**2*d*EZ3**2*(1 + (2*b*EZ1 + d*EZ2)*Log(EZ3))
    1390                 :             :         cw(2)=a**2*b**2*EZ1**3*Log(EZ1) - a*d**2*EZ2**2*(1 + (a*EZ1 - 2*d*EZ3)*Log(EZ2)) - &
    1391                 :             :               b*d**2*EZ3**2*(1 + (b*EZ1 + 2*d*EZ2)*Log(EZ3))
    1392                 :             :         cw(3)=a*b**3*EZ1**3*Log(EZ1) - a*d**3*EZ2**3*Log(EZ2) + b*d*EZ3*(half + b*EZ1 + d*EZ2 + &
    1393                 :             :              (b**2*EZ1**2 + b*d*EZ1*EZ2 + d**2*EZ2**2)*Log(EZ3))
    1394                 :             :         cw(4)=a*b**3*EZ1**3*Log(EZ1) - a*d**3*EZ2**3*Log(EZ2) + b*d*EZ3*(half + b*EZ1 + d*EZ2 + &
    1395                 :             :              (b**2*EZ1**2 + b*d*EZ1*EZ2 + d**2*EZ2**2)*Log(EZ3))
    1396                 :             : #else
    1397         [ #  # ]:           0 :         call SIM0TWOI(cw, VERLI, z-eig)
    1398                 :             : #endif
    1399                 :             :     !    e2=e3
    1400         [ #  # ]:           0 :     elseif ( E23 .lt. tol ) then
    1401                 :             : #if 0
    1402                 :             :         !print *, "e2=e3"
    1403                 :             :         cw(1)=-(a**2*c*EZ1**2*(-1 + (2*a*EZ2 + c*EZ4)*Log(EZ1))) + &
    1404                 :             :                 a**2*e*EZ2**2*(1 + (2*a*EZ1 - e*EZ4)*Log(EZ2)) + c**2*e**2*EZ4**3*Log(EZ4)
    1405                 :             :         cw(2)=a**3*c*EZ1**3*Log(EZ1) - &
    1406                 :             :               a*e*EZ2*(half + a*EZ1 - e*EZ4 + (a**2*EZ1**2 - a*e*EZ1*EZ4 + e**2*EZ4**2)*Log(EZ2)) + c*e**3*EZ4**3*Log(EZ4)
    1407                 :             :         cw(3)=a**3*c*EZ1**3*Log(EZ1) - &
    1408                 :             :               a*e*EZ2*(half + a*EZ1 - e*EZ4 + (a**2*EZ1**2 - a*e*EZ1*EZ4 + e**2*EZ4**2)*Log(EZ2)) + c*e**3*EZ4**3*Log(EZ4)
    1409                 :             :         cw(4)=a**2*c**2*EZ1**3*Log(EZ1) - &
    1410                 :             :               a*e**2*EZ2**2*(1 + (a*EZ1 - 2*e*EZ4)*Log(EZ2)) - c*e**2*EZ4**2*(1 + (c*EZ1 + 2*e*EZ2)*Log(EZ4))
    1411                 :             : #else
    1412         [ #  # ]:           0 :         call SIM0TWOI(cw, VERLI, z-eig)
    1413                 :             : #endif
    1414                 :             : 
    1415                 :             :     ! e1=e2
    1416         [ #  # ]:           0 :     elseif ( E12 .lt. tol ) then
    1417                 :             :         !print *, "e1=e2"
    1418                 :             : #if 0
    1419                 :             :         cw(1)=b*c*EZ1*(half - b*EZ3 - c*EZ4 + (b**2*EZ3**2 + b*c*EZ3*EZ4 + c**2*EZ4**2)*Log(EZ1)) - &
    1420                 :             :               b**3*EZ3**3*f*Log(EZ3) + c**3*EZ4**3*f*Log(EZ4)
    1421                 :             :         cw(2)=b*c*EZ1*(half - b*EZ3 - c*EZ4 + (b**2*EZ3**2 + b*c*EZ3*EZ4 + c**2*EZ4**2)*Log(EZ1)) - &
    1422                 :             :               b**3*EZ3**3*f*Log(EZ3) + c**3*EZ4**3*f*Log(EZ4)
    1423                 :             :         cw(3)=-(b**2*c*EZ1**2*(-1 + (2*b*EZ3 + c*EZ4)*Log(EZ1))) + &
    1424                 :             :                 b**2*EZ3**2*f*(1 + (2*b*EZ1 - EZ4*f)*Log(EZ3)) + c**2*EZ4**3*f**2*Log(EZ4)
    1425                 :             :         cw(4)=-(b*c**2*EZ1**2*(-1 + (b*EZ3 + 2*c*EZ4)*Log(EZ1))) + &
    1426                 :             :                 b**2*EZ3**3*f**2*Log(EZ3) - c**2*EZ4**2*f*(1 + (2*c*EZ1 + EZ3*f)*Log(EZ4))
    1427                 :             : #else
    1428         [ #  # ]:           0 :         call SIM0TWOI(cw, VERLI, z-eig)
    1429                 :             : #endif
    1430                 :             :     ! e1<e2<e3<e4
    1431                 :             :     else
    1432                 :             :         !print *, "e1<e2<e3<e4"
    1433                 :             : #if 0
    1434                 :             :         cw(1)=a**2*d*e*EZ2**3*Log(EZ2/EZ1) - b**2*d*EZ3**3*f*Log(EZ3/EZ1) + c*(a*b*EZ1**2 + c*e*EZ4**3*f*Log(EZ4/EZ1))
    1435                 :             :         cw(2)=a**2*b*c*EZ1**3*Log(EZ1/EZ2) - b*d**2*EZ3**3*f*Log(EZ3/EZ2) + e*(-(a*d*EZ2**2) + c*e*EZ4**3*f*Log(EZ4/EZ2))
    1436                 :             :         cw(3)=a*b**2*c*EZ1**3*Log(EZ1/EZ3) - a*d**2*e*EZ2**3*Log(EZ2/EZ3) + f*(b*d*EZ3**2 + c*e*EZ4**3*f*Log(EZ4/EZ3))
    1437                 :             :         cw(4)=a*b*c**2*EZ1**3*Log(EZ1/EZ4) - a*d*e**2*EZ2**3*Log(EZ2/EZ4) + f*(-(c*e*EZ4**2) + b*d*EZ3**3*f*Log(EZ3/EZ4))
    1438                 :             : #else
    1439                 :             :         !do ii=1,4
    1440                 :             :         !  cw(ii) = zme(ii) ** 2 / prod_wo(ii)
    1441                 :             :         !  do jj=1,4
    1442                 :             :         !    if (jj == ii) cycle
    1443                 :             :         !    cw(ii) = cw(ii) + (zme(jj)**3 / prod_wo(jj) * log(zme(jj) / zme(ii)) / (eig(ii) - eig(jj)))
    1444                 :             :         !  end do
    1445                 :             :         !end do
    1446                 :             : 
    1447         [ #  # ]:           0 :         call SIM0TWOI(cw, VERLI, z-eig)
    1448                 :             : #endif
    1449                 :             :     endif
    1450                 :             : 
    1451                 :             :     ! HM:check this
    1452                 :             :     !cw = cw * two
    1453                 :             : 
    1454                 :             :  contains
    1455                 :             :  pure real(dp) function prod_wo(ii)
    1456                 :             :     integer,intent(in) :: ii
    1457                 :             :     integer  :: kk
    1458                 :             : 
    1459                 :             :     prod_wo = one
    1460                 :             :     do kk=1,4
    1461                 :             :        if (kk == ii) cycle
    1462                 :             :        prod_wo = prod_wo * (eig(kk) - eig(ii))
    1463                 :             :     end do
    1464                 :             :  end function prod_wo
    1465                 :             : 
    1466                 :             : end subroutine get_onetetra_lambinvigneron
    1467                 :             : !!***
    1468                 :             : 
    1469                 :             : !!****f* m_htetra/get_ontetratra_lambinvigneron_imag
    1470                 :             : !! NAME
    1471                 :             : !! get_ontetratra_lambinvigneron_imag
    1472                 :             : !!
    1473                 :             : !! FUNCTION
    1474                 :             : !!  Compute the complex weights according to:
    1475                 :             : !!  P. Lambin and J.P. Vigneron, Phys. Rev. B 29, 3430 (1984)
    1476                 :             : !!  This routine is adapted from tdep where it was implemented
    1477                 :             : !!  by Olle Hellman, all credits go to him
    1478                 :             : !!
    1479                 :             : !! INPUTS
    1480                 :             : !!
    1481                 :             : !! OUTPUT
    1482                 :             : !!
    1483                 :             : !! SOURCE
    1484                 :             : 
    1485                 :           0 : pure subroutine get_onetetetra_lambinvigneron_imag(eig, energies, nene, wt)
    1486                 :             : 
    1487                 :             :  ! dispersion values at the corners of the tetrahedron
    1488                 :             :  real(dp), intent(in), dimension(4) :: eig
    1489                 :             :  ! number of energies
    1490                 :             :  integer, intent(in) :: nene
    1491                 :             :  ! energy to evaluate the weights at
    1492                 :             :  real(dp), intent(in) :: energies(nene)
    1493                 :             :  ! integration weights
    1494                 :             :  real(dp), intent(out) :: wt(4,nene)
    1495                 :             : 
    1496                 :             :  integer :: ie
    1497                 :             :  real(dp) :: z
    1498                 :             :  real(dp) :: EZ1,EZ2,EZ3,EZ4
    1499                 :             :  real(dp) :: Emin,Emax
    1500                 :             :  real(dp) :: E12,E13,E14,E23,E24,E34
    1501                 :             :  real(dp) :: a,b,c,d,e,f,ff0,ff1,ff2,ff3,gg0,gg1,gg2,gg3,hh0,hh1,hh2,hh3,ii0,ii1,ii2,ii3
    1502                 :             : 
    1503   [ #  #  #  # ]:           0 :  wt = zero
    1504                 :             :  Emin = eig(1)
    1505                 :             :  Emax = eig(4)
    1506                 :             : 
    1507         [ #  # ]:           0 :  do ie=1,nene
    1508                 :           0 :    z = energies(ie)
    1509         [ #  # ]:           0 :    if (z<eig(1)) then ! e<e1<e2<e3<e4
    1510                 :             :      cycle
    1511         [ #  # ]:           0 :    else if (z .lt. eig(2)) then ! e1<e<e2<e3<e4
    1512                 :           0 :      EZ1=z-eig(1)
    1513                 :           0 :      EZ2=z-eig(2)
    1514                 :           0 :      EZ3=z-eig(3)
    1515                 :           0 :      EZ4=z-eig(4)
    1516                 :           0 :      E12=eig(2)-eig(1)
    1517                 :           0 :      E13=eig(3)-eig(1)
    1518                 :           0 :      E14=eig(4)-eig(1)
    1519                 :           0 :      a=one/E12
    1520                 :           0 :      b=one/E13
    1521                 :           0 :      c=one/E14
    1522                 :           0 :      wt(1,ie)=a*b*c*EZ1**2*(-a*EZ2 - b*EZ3 - c*EZ4)
    1523                 :           0 :      wt(2,ie)=a**2*b*c*EZ1**3
    1524                 :           0 :      wt(3,ie)=a*b**2*c*EZ1**3
    1525                 :           0 :      wt(4,ie)=a*b*c**2*EZ1**3
    1526                 :           0 :      cycle
    1527         [ #  # ]:           0 :    else if (z .lt. eig(3)) then ! e1<e2<e<e3<e4
    1528                 :           0 :      EZ1=z-eig(1)
    1529                 :           0 :      EZ2=z-eig(2)
    1530                 :           0 :      EZ3=z-eig(3)
    1531                 :           0 :      EZ4=z-eig(4)
    1532                 :           0 :      E13=eig(3)-eig(1)
    1533                 :           0 :      E14=eig(4)-eig(1)
    1534                 :           0 :      E23=eig(3)-eig(2)
    1535                 :           0 :      E24=eig(4)-eig(2)
    1536                 :           0 :      b=one/E13
    1537                 :           0 :      c=one/E14
    1538                 :           0 :      d=one/E23
    1539                 :           0 :      e=one/E24
    1540                 :           0 :      ff0=-b**2*EZ3
    1541                 :           0 :      ff2=-c**2*EZ4
    1542                 :           0 :      gg0=-d**2*EZ3
    1543                 :           0 :      gg2=-e**2*EZ4
    1544                 :           0 :      hh0=d**2*EZ2
    1545                 :           0 :      hh2=b**2*EZ1
    1546                 :           0 :      ii0=e**2*EZ2
    1547                 :           0 :      ii2=c**2*EZ1
    1548                 :           0 :      ff1=-c*d*EZ1*EZ3-d*e*EZ2*EZ3-c*e*EZ1*EZ4
    1549                 :           0 :      ff3=-b*d*EZ1*EZ3-b*e*EZ1*EZ4-d*e*EZ2*EZ4
    1550                 :           0 :      gg1=-b*c*EZ1*EZ3-b*e*EZ2*EZ3-c*e*EZ2*EZ4
    1551                 :           0 :      gg3=-b*d*EZ2*EZ3-b*c*EZ1*EZ4-c*d*EZ2*EZ4
    1552                 :           0 :      hh1=-b*c*EZ1*EZ3-b*e*EZ2*EZ3-c*e*EZ2*EZ4
    1553                 :           0 :      hh3=-c*d*EZ1*EZ3-d*e*EZ2*EZ3-c*e*EZ1*EZ4
    1554                 :           0 :      ii1=-b*d*EZ2*EZ3-b*c*EZ1*EZ4-c*d*EZ2*EZ4
    1555                 :           0 :      ii3=-b*d*EZ1*EZ3-b*e*EZ1*EZ4-d*e*EZ2*EZ4
    1556                 :           0 :      wt(1,ie)=half*(ff0*ff1+ff2*ff3)
    1557                 :           0 :      wt(2,ie)=half*(gg0*gg1+gg2*gg3)
    1558                 :           0 :      wt(3,ie)=half*(hh0*hh1+hh2*hh3)
    1559                 :           0 :      wt(4,ie)=half*(ii0*ii1+ii2*ii3)
    1560                 :           0 :      cycle
    1561         [ #  # ]:           0 :    else if (z .lt. eig(4)) then ! e1<e2<e3<e<e4
    1562                 :           0 :      EZ1=z-eig(1)
    1563                 :           0 :      EZ2=z-eig(2)
    1564                 :           0 :      EZ3=z-eig(3)
    1565                 :           0 :      EZ4=z-eig(4)
    1566                 :           0 :      E14=eig(4)-eig(1)
    1567                 :           0 :      E24=eig(4)-eig(2)
    1568                 :           0 :      E34=eig(4)-eig(3)
    1569                 :           0 :      c=one/E14
    1570                 :           0 :      e=one/E24
    1571                 :           0 :      f=one/E34
    1572                 :           0 :      wt(1,ie)=-(c**2*e*EZ4**3*f)
    1573                 :           0 :      wt(2,ie)=-(c*e**2*EZ4**3*f)
    1574                 :           0 :      wt(3,ie)=-(c*e*EZ4**3*f**2)
    1575                 :           0 :      wt(4,ie)=c*e*EZ4**2*f*(c*EZ1 + e*EZ2 + EZ3*f)
    1576                 :           0 :      cycle
    1577                 :             :    else
    1578                 :           0 :      exit
    1579                 :             :    end if
    1580                 :             :  end do
    1581   [ #  #  #  # ]:           0 :  wt = wt*4.0_dp
    1582                 :             : 
    1583                 :           0 : end subroutine get_onetetetra_lambinvigneron_imag
    1584                 :             : !!***
    1585                 :             : 
    1586                 :             : !----------------------------------------------------------------------
    1587                 :             : 
    1588                 :             : !!****f* m_htetra/htetra_get_onewk_wvals
    1589                 :             : !! NAME
    1590                 :             : !! htetra_get_onewk_wvals
    1591                 :             : !!
    1592                 :             : !! FUNCTION
    1593                 :             : !! Calculate integration weights and their derivatives for a single k-point in the IBZ.
    1594                 :             : !!
    1595                 :             : !! INPUTS
    1596                 :             : !! ik_ibz=Index of the k-point in the IBZ array
    1597                 :             : !! bcorr=1 to include Blochl correction else 0.
    1598                 :             : !! nw=number of energies in wvals
    1599                 :             : !! nibz=number of irreducible kpoints
    1600                 :             : !! wvals(nw)=Frequency points.
    1601                 :             : !! eigen_ibz(nkibz)=eigenenergies for each k point
    1602                 :             : !!
    1603                 :             : !! OUTPUT
    1604                 :             : !!  weights(nw,2) = integration weights for
    1605                 :             : !!    Dirac delta (derivative of theta wrt energy) and Theta (Heaviside function)
    1606                 :             : !!    for a given (band, k-point, spin).
    1607                 :             : !!
    1608                 :             : !! SOURCE
    1609                 :             : 
    1610                 :      100721 : subroutine htetra_get_onewk_wvals(tetra, ik_ibz, opt, nw, wvals, max_occ, nkibz, eig_ibz, weights)
    1611                 :             : 
    1612                 :             : !Arguments ------------------------------------
    1613                 :             : !scalars
    1614                 :             :  class(htetra_t), intent(inout) :: tetra
    1615                 :             :  integer,intent(in) :: ik_ibz,nw,nkibz,opt
    1616                 :             :  real(dp),intent(in) :: max_occ
    1617                 :             : !arrays
    1618                 :             :  real(dp),intent(in) :: wvals(nw), eig_ibz(nkibz)
    1619                 :             :  real(dp),intent(out) :: weights(nw, 2)
    1620                 :             : 
    1621                 :             : !Local variables-------------------------------
    1622                 :             : !scalars
    1623                 :             :  integer  :: itetra,isummit,tetra_count,tetra_total
    1624                 :             :  real(dp) :: tweight
    1625                 :             : !arrays
    1626                 :             :  integer  :: ind_ibz(4),tetra_mibz(0:4)
    1627                 :      100721 :  real(dp) :: eig(4), tweight_tmp(4,nw),dweight_tmp(4,nw)
    1628                 :             : ! *********************************************************************
    1629                 :             : 
    1630   [ +  +  +  + ]:   224806779 :  weights = zero
    1631                 :             :  ! lazy evaluation of the mapping from k-points to tetrahedra
    1632         [ +  + ]:      100721 :  if (.not.allocated(tetra%ibz)) call htetra_init_mapping_ibz(tetra)
    1633                 :             : 
    1634                 :             :  ! For each tetrahedron that belongs to this k-point
    1635                 :      100721 :  tetra_count = tetra%tetra_count(ik_ibz)
    1636                 :      100721 :  tetra_total = tetra%tetra_total(ik_ibz)
    1637         [ +  + ]:    15810881 :  do itetra=1,tetra_count
    1638                 :             : 
    1639                 :    15710160 :    call htetra_get_ibz(tetra, ik_ibz, itetra, tetra_mibz)
    1640                 :    15710160 :    tweight = one*tetra_mibz(0) / tetra_total
    1641         [ +  + ]:    78550800 :    do isummit=1,4
    1642                 :             :      ! Get mapping of each summit to eig_ibz
    1643                 :    62840640 :      ind_ibz(isummit) = tetra_mibz(isummit)
    1644                 :    78550800 :      eig(isummit) = eig_ibz(ind_ibz(isummit))
    1645                 :             :    end do
    1646                 :             : 
    1647                 :             :    ! Sort energies before calling get_onetetra_blochl
    1648                 :    15710160 :    call sort_4tetra(eig, ind_ibz)
    1649                 :             : 
    1650                 :             :    ! HM: Here we should only compute what we will use!
    1651                 :    31420320 :    select case (opt)
    1652                 :             :    case (0:1)
    1653                 :    15710160 :      call get_onetetra_blochl(eig, wvals, nw, opt, tweight_tmp, dweight_tmp)
    1654                 :             :    case (2)
    1655                 :           0 :      call get_onetetetra_lambinvigneron_imag(eig, wvals, nw, dweight_tmp)
    1656   [ +  -  -  -  :    15710160 :      tweight_tmp = zero
                -  -  - ]
    1657                 :             :    end select
    1658                 :             : 
    1659                 :             :    ! Accumulate contributions to ik_ibz (there might be multiple vertices that map onto ik_ibz)
    1660         [ +  - ]:    38922106 :    do isummit=1,4
    1661         [ +  + ]:    38821385 :      if (ind_ibz(isummit) /= ik_ibz) cycle
    1662         [ +  + ]: 13286034336 :      weights(:,1) = weights(:,1) + dweight_tmp(isummit,:)*tweight*max_occ
    1663         [ +  + ]: 13286034336 :      weights(:,2) = weights(:,2) + tweight_tmp(isummit,:)*tweight*max_occ
    1664                 :             :      ! HM: This exit is important, avoids summing the same contribution more than once
    1665                 :    23111225 :      exit
    1666                 :             :    end do
    1667                 :             :  end do ! itetra
    1668                 :             : 
    1669                 :      100721 : end subroutine htetra_get_onewk_wvals
    1670                 :             : !!***
    1671                 :             : 
    1672                 :             : !----------------------------------------------------------------------
    1673                 :             : 
    1674                 :             : !!****f* m_htetra/tetra_get_onewk
    1675                 :             : !! NAME
    1676                 :             : !! tetra_get_onewk
    1677                 :             : !!
    1678                 :             : !! FUNCTION
    1679                 :             : !! Calculate integration weights and their derivatives for a single k-point in the IBZ.
    1680                 :             : !! Same as above but different calling arguments.
    1681                 :             : !! IBZ Weights are not included
    1682                 :             : !! HM: The above is preferred but I keep this one to ease the transition
    1683                 :             : !!
    1684                 :             : !! INPUTS
    1685                 :             : !!
    1686                 :             : !! OUTPUT
    1687                 :             : !!
    1688                 :             : !! SOURCE
    1689                 :             : 
    1690                 :       12326 : subroutine htetra_get_onewk(tetra, ik_ibz, bcorr, nw, nkibz, eig_ibz, enemin, enemax, max_occ, weights)
    1691                 :             : 
    1692                 :             : !Arguments ------------------------------------
    1693                 :             : !scalars
    1694                 :             :  class(htetra_t), intent(inout) :: tetra
    1695                 :             :  integer,intent(in) :: ik_ibz,nw,nkibz,bcorr
    1696                 :             :  real(dp) ,intent(in) :: enemin,enemax,max_occ
    1697                 :             : !arrays
    1698                 :             :  real(dp),intent(in) :: eig_ibz(nkibz)
    1699                 :             :  real(dp),intent(out) :: weights(nw,2)
    1700                 :             : 
    1701                 :             : !Local variables-------------------------------
    1702                 :             : !scalars
    1703                 :       12326 :  real(dp) :: wvals(nw)
    1704                 :             : ! *********************************************************************
    1705                 :             : 
    1706   [ +  +  +  + ]:    63510798 :  weights = zero
    1707                 :       12326 :  wvals = linspace(enemin, enemax, nw)
    1708                 :       12326 :  call htetra_get_onewk_wvals(tetra, ik_ibz, bcorr, nw, wvals, max_occ, nkibz, eig_ibz, weights)
    1709                 :             : 
    1710                 :       12326 : end subroutine htetra_get_onewk
    1711                 :             : !!***
    1712                 :             : 
    1713                 :             : !----------------------------------------------------------------------
    1714                 :             : 
    1715                 :             : !!****f* m_htetra/htetra_get_onewk_wvals_zinv
    1716                 :             : !! NAME
    1717                 :             : !! htetra_get_onewk_wvals_zinv
    1718                 :             : !!
    1719                 :             : !! FUNCTION
    1720                 :             : !! Calculate integration weights for 1/(z-E(k)) for a single k-point in the IBZ.
    1721                 :             : !! Using either the implementation from:
    1722                 :             : !! S. Kaprzyk, Computer Physics Communications 183, 347 (2012).
    1723                 :             : !! or (TODO)
    1724                 :             : !! P. Lambin and J.P. Vigneron, Phys. Rev. B 29, 3430 (1984).
    1725                 :             : !!
    1726                 :             : !! INPUTS
    1727                 :             : !! ik_ibz=Index of the k-point in the IBZ array
    1728                 :             : !! bcorr=1 to include Blochl correction else 0.
    1729                 :             : !! nw=number of energies in wvals
    1730                 :             : !! nibz=number of irreducible kpoints
    1731                 :             : !! wvals(nw)=Frequency points.
    1732                 :             : !! eigen_ibz(nkibz)=eigenenergies for each k point
    1733                 :             : !! opt: 1 for S. Kaprzyk routines, 2 for Lambin.
    1734                 :             : !!
    1735                 :             : !! OUTPUT
    1736                 :             : !!  weights(nw,2) = integration weights for
    1737                 :             : !!    Dirac delta (derivative of theta wrt energy) and Theta (Heaviside function)
    1738                 :             : !!    for a given (band, k-point, spin).
    1739                 :             : !!  [erange(2)]: if present, weights are computed with an approximated asyntotic expression if
    1740                 :             : !!   real(z) is outside of this interval and with tetra if inside.
    1741                 :             : !!
    1742                 :             : !! SOURCE
    1743                 :             : 
    1744                 :           0 : subroutine htetra_get_onewk_wvals_zinv(tetra, ik_ibz, nz, zvals, max_occ, nkibz, eig_ibz, opt, cweights, erange)
    1745                 :             : 
    1746                 :             : !Arguments ------------------------------------
    1747                 :             : !scalars
    1748                 :             :  class(htetra_t), intent(inout) :: tetra
    1749                 :             :  integer,intent(in) :: ik_ibz,nz,nkibz,opt
    1750                 :             :  real(dp) ,intent(in) :: max_occ
    1751                 :             : !arrays
    1752                 :             :  complex(dp),intent(in) :: zvals(nz)
    1753                 :             :  real(dp),optional,intent(in) :: erange(2)
    1754                 :             :  real(dp),intent(in) :: eig_ibz(nkibz)
    1755                 :             :  complex(dp),intent(out) :: cweights(nz)
    1756                 :             : 
    1757                 :             : !Local variables-------------------------------
    1758                 :             : !scalars
    1759                 :             :  integer  :: itetra,isummit,tetra_total,tetra_count,iz
    1760                 :             :  real(dp) :: tweight
    1761                 :             : !arrays
    1762                 :             :  integer  :: ind_ibz(4),tetra_mibz(0:4)
    1763                 :             :  real(dp) :: eig(4), my_erange(2)
    1764                 :             :  complex(dp) :: verm(4), cw(4), verli(4)
    1765                 :             : ! *********************************************************************
    1766                 :             : 
    1767         [ #  # ]:           0 :  cweights = zero
    1768                 :             :  ! lazy evaluation of the mapping from k-points to tetrahedra
    1769         [ #  # ]:           0 :  if (.not.allocated(tetra%ibz)) call htetra_init_mapping_ibz(tetra)
    1770                 :             : 
    1771         [ #  # ]:           0 :  if (all(opt /= [1, 2])) then
    1772                 :           0 :    ABI_ERROR(sjoin("Invalid opt:", itoa(opt)))
    1773                 :             :  end if
    1774                 :             : 
    1775         [ #  # ]:           0 :  my_erange = [-huge(one), huge(one)]; if (present(erange)) my_erange = erange
    1776                 :             : 
    1777                 :             :  ! For each tetrahedron that belongs to this k-point
    1778                 :           0 :  tetra_count = tetra%tetra_count(ik_ibz)
    1779                 :           0 :  tetra_total = tetra%tetra_total(ik_ibz)
    1780         [ #  # ]:           0 :  do itetra=1,tetra_count
    1781                 :             : 
    1782                 :           0 :    call htetra_get_ibz(tetra, ik_ibz, itetra, tetra_mibz)
    1783                 :           0 :    tweight = one * tetra_mibz(0) / tetra_total
    1784         [ #  # ]:           0 :    do isummit=1,4
    1785                 :             :      ! Get mapping of each summit to eig_ibz
    1786                 :           0 :      ind_ibz(isummit) = tetra_mibz(isummit)
    1787                 :           0 :      eig(isummit) = eig_ibz(ind_ibz(isummit))
    1788                 :             :    end do
    1789                 :             : 
    1790                 :             :    ! Loop over frequencies
    1791         [ #  # ]:           0 :    do iz=1,nz
    1792                 :             : 
    1793   [ #  #  #  # ]:           0 :      if (real(zvals(iz)) >= my_erange(1) .and. real(zvals(iz)) <= my_erange(2)) then
    1794                 :           0 :        select case(opt)
    1795                 :             :        case (1)
    1796         [ #  # ]:           0 :          verm = zvals(iz) - eig
    1797                 :           0 :          call SIM0TWOI(cw, VERLI, VERM)
    1798                 :             :        case (2)
    1799      [ #  #  # ]:           0 :          call get_onetetra_lambinvigneron(eig, zvals(iz), cw)
    1800                 :             :        end select
    1801                 :             :      else
    1802         [ #  # ]:           0 :        cw = (one / (zvals(iz) - eig)) / four !* tetra%vv
    1803                 :             :      end if
    1804                 :             : 
    1805         [ #  # ]:           0 :      do isummit=1,4
    1806         [ #  # ]:           0 :        if (ind_ibz(isummit) /= ik_ibz) cycle
    1807                 :           0 :        cweights(iz) = cweights(iz) + cw(isummit) * tweight * max_occ
    1808                 :             :        ! HM: This exit is important, avoids summing the same contribution more than once
    1809                 :           0 :        exit
    1810                 :             :      end do
    1811                 :             :    end do
    1812                 :             :  end do ! itetra
    1813                 :             : 
    1814                 :           0 : end subroutine htetra_get_onewk_wvals_zinv
    1815                 :             : !!***
    1816                 :             : 
    1817                 :             : !----------------------------------------------------------------------
    1818                 :             : 
    1819                 :             : !!****f* m_htetra/htetra_get_delta_mask
    1820                 :             : !! NAME
    1821                 :             : !!  htetra_get_delta_mask
    1822                 :             : !!
    1823                 :             : !! FUNCTION
    1824                 :             : !!  Get a mask for the kpoints where the delta is finite
    1825                 :             : !!
    1826                 :             : 
    1827                 :             : subroutine htetra_get_delta_mask(tetra, eig_ibz, wvals, nw, nkpt, kmask, comm)
    1828                 :             : 
    1829                 :             : !Arguments
    1830                 :             :  class(htetra_t), intent(in) :: tetra
    1831                 :             :  integer,intent(in) :: nw,nkpt,comm
    1832                 :             :  real(dp),intent(in) :: wvals(nw)
    1833                 :             :  real(dp),intent(in) :: eig_ibz(nkpt)
    1834                 :             :  integer,intent(out) :: kmask(nkpt)
    1835                 :             : 
    1836                 :             : !Local variables-------------------------------
    1837                 :             :  integer :: ik_ibz,nprocs,my_rank,ierr, contrib
    1838                 :             :  integer :: tetra_count, itetra, isummit, ihash
    1839                 :             :  real(dp) :: emin,emax
    1840                 :             :  integer :: ind_ibz(4)
    1841                 :             :  real(dp) :: eig(4)
    1842                 :             : 
    1843                 :             :  nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
    1844                 :             :  kmask = 0
    1845                 :             :  ! For each bucket of tetrahedra
    1846                 :             :  do ihash=1,tetra%nbuckets
    1847                 :             :    if (mod(ihash,nprocs) /= my_rank) cycle
    1848                 :             : 
    1849                 :             :    ! For each tetrahedron
    1850                 :             :    tetra_count = size(tetra%unique_tetra(ihash)%indexes, dim=2)
    1851                 :             :    do itetra=1,tetra_count
    1852                 :             : 
    1853                 :             :      ! Get mapping of each summit to eig_ibz
    1854                 :             :      do isummit=1,4
    1855                 :             :        ind_ibz(isummit) = tetra%unique_tetra(ihash)%indexes(isummit, itetra)
    1856                 :             :        eig(isummit) = eig_ibz(ind_ibz(isummit))
    1857                 :             :      end do
    1858                 :             : 
    1859                 :             :      ! Determine the energy range of the tetrahedra
    1860                 :             :      emin = minval(eig)
    1861                 :             :      emax = maxval(eig)
    1862                 :             : 
    1863                 :             :      ! Check if any value in wvals is between emin and emax
    1864                 :             :      contrib = 0; if (any(emin < wvals .and. wvals < emax)) contrib = 1
    1865                 :             : 
    1866                 :             :      ! Compute the union
    1867                 :             :      do isummit=1,4
    1868                 :             :        ik_ibz = ind_ibz(isummit)
    1869                 :             :        kmask(ik_ibz) = kmask(ik_ibz) + contrib
    1870                 :             :      end do
    1871                 :             :    end do ! itetra
    1872                 :             :  end do
    1873                 :             : 
    1874                 :             :  call xmpi_sum(kmask, comm, ierr)
    1875                 :             : 
    1876                 :             : end subroutine htetra_get_delta_mask
    1877                 :             : !!***
    1878                 :             : 
    1879                 :             : !----------------------------------------------------------------------
    1880                 :             : 
    1881                 :             : !!****f* m_htetra/htetra_wvals_weights
    1882                 :             : !! NAME
    1883                 :             : !!  htetra_wvals_weights
    1884                 :             : !!
    1885                 :             : !! FUNCTION
    1886                 :             : !!   Emulates the behaviour of the previous tetrahedron implementation but
    1887                 :             : !!   taking a list of energies as input.
    1888                 :             : !!
    1889                 :             : !!   HM: I find that in many routines its better to change the implementation
    1890                 :             : !!   and accumulate the tetrahedron weights in the same way as the
    1891                 :             : !!   gaussian smearing weights using htetra_get_onewk_wvals. However this requires
    1892                 :             : !!   some refactoring of the code. I provide this routine to make it easier
    1893                 :             : !!   to transition to the new tetrahedron implementation without refactoring.
    1894                 :             : !!   Looping over tetrahedra (i.e. using tetra_blochl_weights) is currently faster
    1895                 :             : !!   than looping over k-points.
    1896                 :             : !!
    1897                 :             : !!   MG: Note, however, that tetra_blochl_weights requires more memory as
    1898                 :             : !!       one has to allocate dweight(nw,nkpt),tweight(nw,nkpt) and the size of the arrays increases
    1899                 :             : !!       quickly with the k-mesh and the number of frequencies (propto mband)
    1900                 :             : !!
    1901                 :             : !! INPUTS
    1902                 :             : !!
    1903                 :             : !! OUTPUT
    1904                 :             : !!
    1905                 :             : !! SOURCE
    1906                 :             : 
    1907                 :         118 : subroutine htetra_wvals_weights(tetra, eig_ibz, nw, wvals, max_occ, nkpt, opt, tweight, dweight, comm)
    1908                 :             : 
    1909                 :             : !Arguments ------------------------------------
    1910                 :             : !scalars
    1911                 :             :  integer,intent(in) :: nw,nkpt,opt,comm
    1912                 :             :  class(htetra_t), intent(in) :: tetra
    1913                 :             :  real(dp) ,intent(in) :: max_occ
    1914                 :             : !arrays
    1915                 :             :  real(dp),intent(in) :: eig_ibz(nkpt)
    1916                 :             :  real(dp),intent(out) :: dweight(nw,nkpt),tweight(nw,nkpt)
    1917                 :             : 
    1918                 :             : !Local variables-------------------------------
    1919                 :             : !scalars
    1920                 :             :  integer :: ik_ibz,multiplicity,nprocs,my_rank,ierr
    1921                 :             :  integer :: tetra_count, itetra, isummit, ihash
    1922                 :             : !arrays
    1923                 :             :  integer :: ind_ibz(4)
    1924                 :         118 :  real(dp) :: eig(4), wvals(nw), dweight_tmp(4,nw),tweight_tmp(4,nw)
    1925                 :             : ! *********************************************************************
    1926                 :             : 
    1927   [ +  +  +  +  :    10409956 :  tweight = zero; dweight = zero
             +  +  +  + ]
    1928                 :         118 :  nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
    1929                 :             : 
    1930                 :             :  ! For each bucket of tetrahedra
    1931         [ +  + ]:        5994 :  do ihash=1,tetra%nbuckets
    1932         [ +  - ]:        5876 :    if (mod(ihash, nprocs) /= my_rank) cycle
    1933                 :             : 
    1934                 :             :    ! For each tetrahedron
    1935                 :        5876 :    tetra_count = size(tetra%unique_tetra(ihash)%indexes, dim=2)
    1936         [ +  + ]:      105152 :    do itetra=1,tetra_count
    1937                 :             : 
    1938                 :             :      ! Get mapping of each summit to eig_ibz
    1939         [ +  + ]:      495790 :      do isummit=1,4
    1940                 :      396632 :        ind_ibz(isummit) = tetra%unique_tetra(ihash)%indexes(isummit, itetra)
    1941                 :      495790 :        eig(isummit) = eig_ibz(ind_ibz(isummit))
    1942                 :             :      end do
    1943                 :             : 
    1944                 :             :      ! Sort energies before calling get_onetetra_blochl
    1945                 :       99158 :      call sort_4tetra(eig, ind_ibz)
    1946                 :             : 
    1947                 :             :      ! Get tetrahedron weights
    1948                 :      198316 :      select case (opt)
    1949                 :             :      case (0:1)
    1950                 :       99158 :        call get_onetetra_blochl(eig, wvals, nw, opt, tweight_tmp, dweight_tmp)
    1951                 :             :      case (2)
    1952                 :           0 :        call get_onetetetra_lambinvigneron_imag(eig, wvals, nw, dweight_tmp)
    1953   [ +  -  -  -  :       99158 :        tweight_tmp = zero
                -  -  - ]
    1954                 :             :      end select
    1955                 :             : 
    1956                 :             :      ! Accumulate the contributions
    1957                 :       99158 :      multiplicity = tetra%unique_tetra(ihash)%indexes(0, itetra)
    1958         [ +  + ]:      501666 :      do isummit=1,4
    1959                 :      396632 :        ik_ibz = ind_ibz(isummit)
    1960         [ +  + ]:   337052272 :        dweight(:,ik_ibz) = dweight(:,ik_ibz) + dweight_tmp(isummit,:) * multiplicity * max_occ
    1961         [ +  + ]:   337151430 :        tweight(:,ik_ibz) = tweight(:,ik_ibz) + tweight_tmp(isummit,:) * multiplicity * max_occ
    1962                 :             :      end do
    1963                 :             :    end do ! itetra
    1964                 :             :  end do
    1965                 :             : 
    1966                 :             :  ! Rescale weights
    1967                 :         118 :  select case(tetra%opt)
    1968                 :             :  case (1)
    1969         [ #  # ]:           0 :    do ik_ibz=1,tetra%nkibz
    1970         [ #  # ]:           0 :      dweight(:,ik_ibz) = dweight(:,ik_ibz) * tetra%ibz_multiplicity(ik_ibz) / tetra%tetra_total(ik_ibz) / tetra%nkbz
    1971         [ #  # ]:           0 :      tweight(:,ik_ibz) = tweight(:,ik_ibz) * tetra%ibz_multiplicity(ik_ibz) / tetra%tetra_total(ik_ibz) / tetra%nkbz
    1972                 :             :    end do
    1973                 :             :  case (2)
    1974   [ +  +  +  + ]:     5204978 :    dweight = dweight*tetra%vv / 4.0_dp
    1975   [ -  +  -  +  :     5205096 :    tweight = tweight*tetra%vv / 4.0_dp
                +  +  + ]
    1976                 :             :  end select
    1977                 :             : 
    1978                 :         118 :  call xmpi_sum(dweight, comm, ierr)
    1979                 :         118 :  call xmpi_sum(tweight, comm, ierr)
    1980                 :             : 
    1981                 :         118 : end subroutine htetra_wvals_weights
    1982                 :             : !!***
    1983                 :             : 
    1984                 :             : !----------------------------------------------------------------------
    1985                 :             : 
    1986                 :             : !!****f* m_htetra/htetra_wvals_weights_delta
    1987                 :             : !! NAME
    1988                 :             : !!  htetra_wvals_weights_delta
    1989                 :             : !!
    1990                 :             : !! FUNCTION
    1991                 :             : !!  Same as above but computing only delta for performance and memory
    1992                 :             : !!  HM: Should find a clean way to avoid copy paste routine
    1993                 :             : !!
    1994                 :             : !! SOURCE
    1995                 :             : 
    1996                 :       30216 : subroutine htetra_wvals_weights_delta(tetra, eig_ibz, nw, wvals, max_occ, nkpt, opt, dweight, comm)
    1997                 :             : 
    1998                 :             : !Arguments ------------------------------------
    1999                 :             : !scalars
    2000                 :             :  class(htetra_t), intent(in) :: tetra
    2001                 :             :  integer,intent(in) :: nw, nkpt, opt, comm
    2002                 :             :  real(dp),intent(in) :: max_occ
    2003                 :             : !arrays
    2004                 :             :  real(dp),intent(in) :: eig_ibz(nkpt), wvals(nw)
    2005                 :             :  real(dp),intent(out) :: dweight(nw, nkpt)
    2006                 :             : 
    2007                 :             : !Local variables-------------------------------
    2008                 :             : !scalars
    2009                 :             :  integer :: ik_ibz,multiplicity,nprocs,my_rank,ierr
    2010                 :             :  integer :: tetra_count, itetra, isummit, ihash
    2011                 :             : !arrays
    2012                 :             :  integer :: ind_ibz(4)
    2013                 :       30216 :  real(dp) :: eig(4), dweight_tmp(4,nw),tweight_tmp(4,nw)
    2014                 :             : ! *********************************************************************
    2015                 :             : 
    2016   [ +  +  +  + ]:    13066728 :  dweight = zero
    2017                 :       30216 :  nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
    2018                 :             : 
    2019                 :             :  ! For each bucket of tetrahedra
    2020         [ +  + ]:     6548472 :  do ihash=1,tetra%nbuckets
    2021         [ +  - ]:     6518256 :    if (mod(ihash, nprocs) /= my_rank) cycle
    2022                 :             : 
    2023                 :             :    ! For each tetrahedron
    2024                 :     6518256 :    tetra_count = size(tetra%unique_tetra(ihash)%indexes, dim=2)
    2025         [ +  + ]:   129322080 :    do itetra=1,tetra_count
    2026                 :             : 
    2027                 :             :      ! Get mapping of each summit to eig_ibz
    2028         [ +  + ]:   613868040 :      do isummit=1,4
    2029                 :   491094432 :        ind_ibz(isummit) = tetra%unique_tetra(ihash)%indexes(isummit,itetra)
    2030                 :   613868040 :        eig(isummit) = eig_ibz(ind_ibz(isummit))
    2031                 :             :      end do
    2032                 :             : 
    2033                 :             :      ! Sort energies before calling get_onetetra_blochl
    2034                 :   122773608 :      call sort_4tetra(eig, ind_ibz)
    2035                 :             : 
    2036                 :             :      ! Get tetrahedron weights
    2037                 :   245547216 :      select case (opt)
    2038                 :             :      case (0:1)
    2039                 :   122773608 :        call get_onetetra_blochl(eig, wvals, nw, opt, tweight_tmp, dweight_tmp)
    2040                 :             :      case (2)
    2041      [ +  -  - ]:   122773608 :        call get_onetetetra_lambinvigneron_imag(eig, wvals, nw, dweight_tmp)
    2042                 :             :      end select
    2043                 :             : 
    2044                 :             :      ! Accumulate the contributions
    2045                 :   122773608 :      multiplicity = tetra%unique_tetra(ihash)%indexes(0,itetra)
    2046         [ +  + ]:   620386296 :      do isummit=1,4
    2047                 :   491094432 :        ik_ibz = ind_ibz(isummit)
    2048         [ +  + ]:  1104962472 :        dweight(:,ik_ibz) = dweight(:,ik_ibz) + dweight_tmp(isummit,:)*multiplicity*max_occ
    2049                 :             :      end do
    2050                 :             :    end do ! itetra
    2051                 :             :  end do
    2052                 :             : 
    2053                 :             :  ! Rescale weights
    2054                 :       30216 :  select case(tetra%opt)
    2055                 :             :  case (1)
    2056         [ #  # ]:           0 :    do ik_ibz=1,tetra%nkibz
    2057         [ #  # ]:           0 :      dweight(:,ik_ibz) = dweight(:,ik_ibz) * tetra%ibz_multiplicity(ik_ibz) / tetra%tetra_total(ik_ibz) / tetra%nkbz
    2058                 :             :    end do
    2059                 :             :  case (2)
    2060   [ -  +  -  +  :    13066728 :    dweight = dweight * tetra%vv / 4.0_dp
                +  +  + ]
    2061                 :             :  end select
    2062                 :             : 
    2063                 :       30216 :  call xmpi_sum(dweight, comm, ierr)
    2064                 :             : 
    2065                 :       30216 : end subroutine htetra_wvals_weights_delta
    2066                 :             : !!***
    2067                 :             : 
    2068                 :             : !----------------------------------------------------------------------
    2069                 :             : 
    2070                 :             : !!****f* m_htetra/htetra_blochl_weights
    2071                 :             : !! NAME
    2072                 :             : !!  htetra_blochl_weights
    2073                 :             : !!
    2074                 :             : !! FUNCTION
    2075                 :             : !!   Emulates the behaviour of the previous tetrahedron implementation.
    2076                 :             : !!   IBZ weights are included.
    2077                 :             : !!
    2078                 :             : !! INPUTS
    2079                 :             : !!
    2080                 :             : !! OUTPUT
    2081                 :             : !!
    2082                 :             : !! SOURCE
    2083                 :             : 
    2084                 :         118 : subroutine htetra_blochl_weights(tetra, eig_ibz, enemin, enemax, max_occ, nw, nkpt, bcorr, tweight, dweight, comm)
    2085                 :             : 
    2086                 :             : !Arguments ------------------------------------
    2087                 :             : !scalars
    2088                 :             :  class(htetra_t), intent(in) :: tetra
    2089                 :             :  integer,intent(in) :: nw,nkpt, bcorr, comm
    2090                 :             :  real(dp),intent(in) :: enemax, enemin, max_occ
    2091                 :             : !arrays
    2092                 :             :  real(dp),intent(in) :: eig_ibz(nkpt)
    2093                 :             :  real(dp),intent(out) :: dweight(nw,nkpt), tweight(nw,nkpt)
    2094                 :             : 
    2095                 :             : !Local variables-------------------------------
    2096                 :         236 :  real(dp) :: wvals(nw)
    2097                 :             : ! *********************************************************************
    2098                 :             : 
    2099                 :         118 :  wvals = linspace(enemin, enemax, nw)
    2100                 :         118 :  call htetra_wvals_weights(tetra,eig_ibz,nw,wvals,max_occ,nkpt,bcorr,tweight,dweight,comm)
    2101                 :             : 
    2102                 :         118 : end subroutine htetra_blochl_weights
    2103                 :             : !!***
    2104                 :             : 
    2105                 :             : !----------------------------------------------------------------------
    2106                 :             : 
    2107                 :             : !!****f* m_htetra/htetra_blochl_weights_wvals_zinv
    2108                 :             : !! NAME
    2109                 :             : !!  htetra_blochl_weights_wvals_zinv
    2110                 :             : !!
    2111                 :             : !! FUNCTION
    2112                 :             : !!  The same as htetra_get_onewk_wvals_zinv but looping over tetrahedra
    2113                 :             : !!  which is more efficient
    2114                 :             : !!
    2115                 :             : !! INPUTS
    2116                 :             : !! nz: Number of frequencies
    2117                 :             : !! zvals(nw): z-values
    2118                 :             : !! max_occ=maximal occupation number (2 for nsppol=1, 1 for nsppol=2)
    2119                 :             : !! nkpt=number of irreducible kpoints
    2120                 :             : !! zinv_opt:
    2121                 :             : !!   1 for S. Kaprzyk routines,
    2122                 :             : !!   2 for Lambin-Vigneron.
    2123                 :             : !!  [erange(2)]: if present, weights are computed with a standard quadrature method if
    2124                 :             : !!     real(z) is outside of this interval and with tetra if inside.
    2125                 :             : !! comm=MPI communicator
    2126                 :             : !!
    2127                 :             : !! OUTPUT
    2128                 :             : !!
    2129                 :             : !! SOURCE
    2130                 :             : 
    2131                 :       18048 : subroutine htetra_weights_wvals_zinv(tetra, eig_ibz, nz, zvals, max_occ, nkpt, zinv_opt, cweight, comm, erange)
    2132                 :             : 
    2133                 :             : !Arguments ------------------------------------
    2134                 :             : !scalars
    2135                 :             :  integer,intent(in) :: nz, nkpt, zinv_opt, comm
    2136                 :             :  class(htetra_t), intent(in) :: tetra
    2137                 :             :  real(dp) ,intent(in) :: max_occ
    2138                 :             : !arrays
    2139                 :             :  real(dp),intent(in) :: eig_ibz(nkpt)
    2140                 :             :  real(dp),optional,intent(in) :: erange(2)
    2141                 :             :  complex(dp),intent(in)  :: zvals(nz)
    2142                 :             :  complex(dp),intent(out) :: cweight(nz, nkpt)
    2143                 :             : 
    2144                 :             : !Local variables-------------------------------
    2145                 :             : !scalars
    2146                 :             :  integer :: ik_ibz, iz, multiplicity, nprocs, my_rank, ierr, ii, jj, kk, esumk
    2147                 :             :  integer :: tetra_count, itetra, isummit, ihash
    2148                 :             : !arrays
    2149                 :             :  integer :: ind_ibz(4)
    2150                 :             :  real(dp) :: eig(4), my_erange(2)
    2151                 :             :  complex(dp) :: cw(4), verli(4), verm(4), aw(4), bw(4) !, cw_lw(4)
    2152                 :       36096 :  real(dp) :: rwg(nz, 4)
    2153                 :             : ! *********************************************************************
    2154                 :             : 
    2155                 :       18048 :  nprocs = xmpi_comm_size(comm); my_rank = xmpi_comm_rank(comm)
    2156   [ +  +  +  + ]:     8541696 :  cweight = zero
    2157                 :             : 
    2158         [ +  - ]:       18048 :  my_erange = [-huge(one), huge(one)]; if (present(erange)) my_erange = erange
    2159                 :             : 
    2160                 :             :  ! For each bucket of tetrahedra
    2161         [ +  + ]:      207552 :  do ihash=1,tetra%nbuckets
    2162         [ +  - ]:      189504 :    if (mod(ihash, nprocs) /= my_rank) cycle
    2163                 :             : 
    2164                 :             :    ! For each tetrahedron that belongs to this k-point
    2165                 :      189504 :    tetra_count = size(tetra%unique_tetra(ihash)%indexes, dim=2)
    2166         [ +  + ]:     1461888 :    do itetra=1,tetra_count
    2167                 :             : 
    2168                 :             :      ! Get mapping of each summit to eig_ibz
    2169         [ +  + ]:     6271680 :      do isummit=1,4
    2170                 :     5017344 :        ind_ibz(isummit) = tetra%unique_tetra(ihash)%indexes(isummit, itetra)
    2171                 :     6271680 :        eig(isummit) = eig_ibz(ind_ibz(isummit))
    2172                 :             :      end do
    2173                 :             : 
    2174                 :             :      ! Get multiplicity
    2175                 :     1254336 :      multiplicity = tetra%unique_tetra(ihash)%indexes(0, itetra)
    2176                 :             : 
    2177                 :             :      ! Sort energies before calling get_onetetra_lambinvigneron
    2178                 :             :      ! SIM0TWOI does not require sorted energies but since we call the routine
    2179                 :             :      ! to fix get_onetetra_lambinvigneron we need to sort here.
    2180                 :     1254336 :      call sort_4tetra(eig, ind_ibz)
    2181                 :             : 
    2182         [ +  - ]:     1443840 : if (zinv_opt == 1) then
    2183                 :             :      ! Loop over frequencies
    2184         [ +  + ]:    56418432 :      do iz=1,nz
    2185                 :             : 
    2186                 :             :        ! Get tetrahedron weights
    2187   [ -  +  -  + ]:    55164096 :        if (real(zvals(iz)) >= my_erange(1) .and. real(zvals(iz)) <= my_erange(2)) then
    2188                 :             : 
    2189                 :    55164096 :          select case(zinv_opt)
    2190                 :             :          case (1)
    2191         [ +  + ]:   275820480 :            verm = zvals(iz) - eig
    2192                 :    55164096 :            call SIM0TWOI(cw, VERLI, VERM)
    2193                 :             : 
    2194                 :             :            !call get_onetetra_lambinvigneron(eig, zvals(iz), cw_lw)
    2195                 :             :            !if (any(abs(real(cw_lw(:)) / (real(cw(:)))) > 1.1)) then
    2196                 :             :            !  do ierr=1,4
    2197                 :             :            !    !write(std_out, *) "simte vs lw:", cw(ierr), cw_lw(ierr)
    2198                 :             :            !    write(std_out, *) "cw_lw / (simtet)", cw_lw(ierr) / (cw(ierr))
    2199                 :             :            !  end do
    2200                 :             :            !end if
    2201                 :             : 
    2202                 :             :          case (2)
    2203                 :             :            call get_onetetra_lambinvigneron(eig, zvals(iz), cw)
    2204                 :             :          end select
    2205                 :             : 
    2206                 :             :        else
    2207                 :             :          ! Use asymptotic expansion of integral for large z.
    2208   [ #  #  #  # ]:           0 :          aw = (eig + sum(eig)) / five
    2209         [ #  # ]:           0 :          do ii=1,4
    2210                 :           0 :            bw(ii) = zero
    2211         [ #  # ]:           0 :            do jj=1,4
    2212         [ #  # ]:           0 :              if (jj == ii) cycle
    2213                 :             :              esumk = zero
    2214         [ #  # ]:           0 :              do kk=1,4
    2215         [ #  # ]:           0 :                if (kk == jj) cycle
    2216                 :           0 :                esumk = esumk + (eig(kk) - eig(jj)) ** 2
    2217                 :             :              end do
    2218                 :           0 :              bw(ii) = bw(ii) + three * (eig(jj) - eig(ii)) ** 2 + esumk
    2219                 :             :            end do
    2220                 :             :          end do
    2221         [ #  # ]:           0 :          bw = bw / 300_dp
    2222         [ #  # ]:           0 :          cw = one / (zvals(iz) - aw - bw / zvals(iz)) / four
    2223                 :             :          !This for naive integration
    2224                 :             :          !cw = (one / (zvals(iz) - eig)) / four
    2225                 :             :        end if
    2226                 :             : 
    2227                 :             :        ! Accumulate contributions
    2228         [ +  + ]:   277074816 :        do isummit=1,4
    2229                 :   220656384 :          ik_ibz = ind_ibz(isummit)
    2230                 :   275820480 :          cweight(iz, ik_ibz) = cweight(iz, ik_ibz) + cw(isummit) * multiplicity * max_occ
    2231                 :             :        end do
    2232                 :             : 
    2233                 :             :      end do ! iz
    2234                 :             : 
    2235                 :             : else
    2236   [ #  #  #  #  :           0 :        call get_onetetra_ppart_lv(nz, real(zvals), eig, rwg)
                   #  # ]
    2237                 :             : 
    2238         [ #  # ]:           0 :        do iz=1,nz
    2239                 :             :          ! Accumulate contributions
    2240         [ #  # ]:           0 :          do isummit=1,4
    2241                 :           0 :            ik_ibz = ind_ibz(isummit)
    2242                 :           0 :            cweight(iz, ik_ibz) = cweight(iz, ik_ibz) + rwg(iz, isummit) * multiplicity * max_occ
    2243                 :             :          end do
    2244                 :             :        end do
    2245                 :             : endif
    2246                 :             : 
    2247                 :             :    end do ! itetra
    2248                 :             :  end do
    2249                 :             : 
    2250                 :             :  ! Rescale weights
    2251                 :       18048 :  select case(tetra%opt)
    2252                 :             :  case (1)
    2253         [ #  # ]:           0 :    do ik_ibz=1,tetra%nkibz
    2254         [ #  # ]:           0 :      cweight(:,ik_ibz) = cweight(:,ik_ibz) * tetra%ibz_multiplicity(ik_ibz) / tetra%nkbz / tetra%tetra_total(ik_ibz)
    2255                 :             :    end do
    2256                 :             :  case (2)
    2257   [ -  +  -  +  :     8541696 :    cweight = cweight * tetra%vv
                +  +  + ]
    2258                 :             :  end select
    2259                 :             : 
    2260                 :       18048 :  call xmpi_sum(cweight, comm, ierr)
    2261                 :             : 
    2262                 :       18048 : end subroutine htetra_weights_wvals_zinv
    2263                 :             : !!***
    2264                 :             : 
    2265                 :             : !----------------------------------------------------------------------
    2266                 :             : 
    2267                 :             : !!****f* m_htetra/sort_4tetra
    2268                 :             : !! NAME
    2269                 :             : !!  sort_4tetra
    2270                 :             : !!
    2271                 :             : !! FUNCTION
    2272                 :             : !!  Sort double precision array list(4) into ascending numerical order
    2273                 :             : !!  while making corresponding rearrangement of the integer array iperm.
    2274                 :             : !!
    2275                 :             : !!  Taken from: https://stackoverflow.com/questions/6145364/sort-4-number-with-few-comparisons
    2276                 :             : !!
    2277                 :             : !! INPUTS
    2278                 :             : !!  list(4) intent(inout) list of double precision numbers to be sorted
    2279                 :             : !!  perm(4) intent(inout) iperm(i)=i (very important)
    2280                 :             : !!
    2281                 :             : !! OUTPUT
    2282                 :             : !!  list(4) sorted list
    2283                 :             : !!  perm(4) index of permutation given the right ascending order
    2284                 :             : !!
    2285                 :             : !! SOURCE
    2286                 :             : 
    2287                 :   139837262 : pure subroutine sort_4tetra(list, perm)
    2288                 :             : 
    2289                 :             :  integer,  intent(inout) :: perm(4)
    2290                 :             :  real(dp), intent(inout) :: list(4)
    2291                 :             : 
    2292                 :             : !Local variables-------------------------------
    2293                 :             :  integer :: ia,ib,ic,id,ilow1,ilow2,ihigh1,ihigh2
    2294                 :             :  integer :: ilowest,ihighest,imiddle1,imiddle2
    2295                 :             :  real(dp) :: va,vb,vc,vd,vlow1,vlow2,vhigh1,vhigh2
    2296                 :             :  real(dp) :: vlowest,vhighest,vmiddle1,vmiddle2
    2297                 :             : 
    2298                 :   139837262 :  va = list(1); ia = perm(1)
    2299                 :   139837262 :  vb = list(2); ib = perm(2)
    2300                 :   139837262 :  vc = list(3); ic = perm(3)
    2301                 :   139837262 :  vd = list(4); id = perm(4)
    2302                 :             : 
    2303         [ +  + ]:   139837262 :  if (va < vb) then
    2304                 :             :      vlow1 = va; vhigh1 = vb
    2305                 :             :      ilow1 = ia; ihigh1 = ib
    2306                 :             :  else
    2307                 :    72940132 :      vlow1 = vb; vhigh1 = va
    2308                 :    72940132 :      ilow1 = ib; ihigh1 = ia
    2309                 :             :  endif
    2310                 :             : 
    2311         [ +  + ]:   139837262 :  if (vc < vd) then
    2312                 :             :      vlow2 = vc; vhigh2 = vd
    2313                 :             :      ilow2 = ic; ihigh2 = id
    2314                 :             :  else
    2315                 :    73080767 :      vlow2 = vd; vhigh2 = vc
    2316                 :    73080767 :      ilow2 = id; ihigh2 = ic
    2317                 :             :  endif
    2318                 :             : 
    2319         [ +  + ]:   139837262 :  if (vlow1 < vlow2) then
    2320                 :             :      vlowest  = vlow1; vmiddle1 = vlow2
    2321                 :             :      ilowest  = ilow1; imiddle1 = ilow2
    2322                 :             :  else
    2323                 :    71288294 :      vlowest  = vlow2; vmiddle1 = vlow1
    2324                 :    71288294 :      ilowest  = ilow2; imiddle1 = ilow1
    2325                 :             :  endif
    2326                 :             : 
    2327         [ +  + ]:   139837262 :  if (vhigh1 > vhigh2) then
    2328                 :             :      vhighest = vhigh1; vmiddle2 = vhigh2
    2329                 :             :      ihighest = ihigh1; imiddle2 = ihigh2
    2330                 :             :  else
    2331                 :    69068729 :      vhighest = vhigh2; vmiddle2 = vhigh1
    2332                 :    69068729 :      ihighest = ihigh2; imiddle2 = ihigh1
    2333                 :             :  endif
    2334                 :             : 
    2335         [ +  + ]:   139837262 :  if (vmiddle1 < vmiddle2) then
    2336         [ +  + ]:   365584920 :      list = [vlowest, vmiddle1, vmiddle2, vhighest]
    2337         [ +  + ]:   365584920 :      perm = [ilowest, imiddle1, imiddle2, ihighest]
    2338                 :             :  else
    2339         [ +  + ]:   333601390 :      list = [vlowest, vmiddle2, vmiddle1, vhighest]
    2340         [ +  + ]:   333601390 :      perm = [ilowest, imiddle2, imiddle1, ihighest]
    2341                 :             :  endif
    2342                 :             : 
    2343                 :   139837262 : end subroutine sort_4tetra
    2344                 :             : !!***
    2345                 :             : 
    2346                 :             : !----------------------------------------------------------------------
    2347                 :             : 
    2348                 :             : !!****f* m_numeric_tools/sort_4tetra_int
    2349                 :             : !! NAME
    2350                 :             : !!  sort_4tetra_int
    2351                 :             : !!
    2352                 :             : !! FUNCTION
    2353                 :             : !!
    2354                 :             : !! INPUTS
    2355                 :             : !!
    2356                 :             : !! OUTPUT
    2357                 :             : !!
    2358                 :             : !! SOURCE
    2359                 :             : 
    2360                 :     8456046 : pure subroutine sort_4tetra_int(list)
    2361                 :             : 
    2362                 :             :  integer, intent(inout) :: list(4)
    2363                 :             : 
    2364                 :             : !Local variables-------------------------------
    2365                 :             :  integer :: va,vb,vc,vd, vlow1,vlow2,vhigh1,vhigh2
    2366                 :             :  integer :: vlowest,vhighest, vmiddle1,vmiddle2
    2367                 :             : 
    2368                 :     8456046 :  va = list(1)
    2369                 :     8456046 :  vb = list(2)
    2370                 :     8456046 :  vc = list(3)
    2371                 :     8456046 :  vd = list(4)
    2372                 :             : 
    2373         [ +  + ]:     8456046 :  if (va < vb) then
    2374                 :             :      vlow1 = va; vhigh1 = vb
    2375                 :             :  else
    2376                 :     4340218 :      vlow1 = vb; vhigh1 = va
    2377                 :             :  endif
    2378                 :             : 
    2379         [ +  + ]:     8456046 :  if (vc < vd) then
    2380                 :             :      vlow2 = vc; vhigh2 = vd
    2381                 :             :  else
    2382                 :     4257565 :      vlow2 = vd; vhigh2 = vc
    2383                 :             :  endif
    2384                 :             : 
    2385         [ +  + ]:     8456046 :  if (vlow1 < vlow2) then
    2386                 :             :      vlowest  = vlow1; vmiddle1 = vlow2
    2387                 :             :  else
    2388                 :     4421792 :      vlowest  = vlow2; vmiddle1 = vlow1
    2389                 :             :  endif
    2390                 :             : 
    2391         [ +  + ]:     8456046 :  if (vhigh1 > vhigh2) then
    2392                 :             :      vhighest = vhigh1; vmiddle2 = vhigh2
    2393                 :             :  else
    2394                 :     4589119 :      vhighest = vhigh2; vmiddle2 = vhigh1
    2395                 :             :  endif
    2396                 :             : 
    2397         [ +  + ]:     8456046 :  if (vmiddle1 < vmiddle2) then
    2398         [ +  + ]:    24813400 :      list = [vlowest, vmiddle1, vmiddle2, vhighest]
    2399                 :             :  else
    2400         [ +  + ]:    17466830 :      list = [vlowest, vmiddle2, vmiddle1, vhighest]
    2401                 :             :  endif
    2402                 :             : 
    2403                 :     8456046 : end subroutine sort_4tetra_int
    2404                 :             : !!***
    2405                 :             : 
    2406                 :             : !!****f* m_htetra/get_onetetra_ppart_lv
    2407                 :             : !! NAME
    2408                 :             : !! get_onetetra_ppart_lv
    2409                 :             : !!
    2410                 :             : !! FUNCTION
    2411                 :             : !!  Compute the complex weights according to: P. Lambin and J.P. Vigneron, Phys. Rev. B 29, 3430 (1984)
    2412                 :             : !!
    2413                 :             : !! INPUTS
    2414                 :             : !!  nw
    2415                 :             : !!  wvals: energy to evaluate the weights at
    2416                 :             : !!  eig: eigenvalues at the corners of the tetrahedron
    2417                 :             : !!
    2418                 :             : !! OUTPUT
    2419                 :             : !!  rwg(nw, 4)
    2420                 :             : !!
    2421                 :             : !! SOURCE
    2422                 :             : 
    2423                 :           0 : pure subroutine get_onetetra_ppart_lv(nw, wvals, eig, rwg)
    2424                 :             : 
    2425                 :             :  integer,intent(in) :: nw
    2426                 :             :  real(dp), intent(in) :: wvals(nw), eig(4)
    2427                 :             :  real(dp), intent(out) :: rwg(nw, 4)
    2428                 :             : 
    2429                 :             : !Local variables-------------------------------
    2430                 :             :  integer :: ii, iw !jj,
    2431                 :             :  real(dp),parameter :: tol = tol14
    2432                 :             :  !real(dp),parameter :: tol = tol20
    2433                 :             :  !real(dp),parameter :: tol = tol30
    2434                 :             :  real(dp) :: D12,D13,D14,D23,D24,D34
    2435                 :             :  real(dp) :: e10, e20, e30, e31, e32, e21
    2436                 :             :  real(dp) :: inv_e10, inv_e21, inv_e20, inv_e30, inv_e31, inv_e32
    2437                 :           0 :  real(dp) :: E0(nw), E1(nw), E2(nw), E3(nw)
    2438                 :             : ! *********************************************************************
    2439                 :             : 
    2440                 :             :  ! Then the energy differences, for the coefficients. Must always be positive, I hope.
    2441                 :           0 :  D12 = eig(2) - eig(1)
    2442                 :           0 :  D13 = eig(3) - eig(1)
    2443                 :           0 :  D14 = eig(4) - eig(1)
    2444                 :           0 :  D23 = eig(3) - eig(2)
    2445                 :           0 :  D24 = eig(4) - eig(2)
    2446                 :           0 :  D34 = eig(4) - eig(3)
    2447                 :             : 
    2448                 :             :  ! Now get the actual weights
    2449                 :             :  ! Notations
    2450                 :             :  !  eij = e_i - e_j
    2451                 :             :  !  Ej = E - e_j
    2452                 :             : 
    2453                 :           0 :  e10 = huge(one);  e20 = huge(one);  e30 = huge(one);
    2454                 :           0 :  e31 = huge(one);  e32 = huge(one);  e21 = huge(one)
    2455                 :           0 :  inv_e10 = huge(one);  inv_e21 = huge(one);  inv_e20 = huge(one)
    2456                 :           0 :  inv_e30 = huge(one);  inv_e31 = huge(one);  inv_e32 = huge(one)
    2457                 :             : 
    2458         [ #  # ]:           0 :  E0 = wvals(:) - eig(1)
    2459         [ #  # ]:           0 :  E1 = wvals(:) - eig(2)
    2460         [ #  # ]:           0 :  E2 = wvals(:) - eig(3)
    2461         [ #  # ]:           0 :  E3 = wvals(:) - eig(4)
    2462                 :             : 
    2463                 :             : #if 0
    2464                 :             :  where (abs(E0) < tol1)
    2465                 :             :    E0 = tol1
    2466                 :             :  end where
    2467                 :             :  where (abs(E1) < tol1)
    2468                 :             :    E1 = tol1
    2469                 :             :  end where
    2470                 :             :  where (abs(E2) < tol1)
    2471                 :             :    E2 = tol1
    2472                 :             :  end where
    2473                 :             :  where (abs(E3) < tol1)
    2474                 :             :    E3 = tol1
    2475                 :             :  end where
    2476                 :             : #endif
    2477                 :             : 
    2478                 :             :  ! e1=e2=e3=e4
    2479         [ #  # ]:           0 :  if (D12 + D23 + D34 < tol) then
    2480         [ #  # ]:           0 :    do ii=1,4
    2481                 :             :      !rwg(:, ii) = 0.25_dp / (wvals - eig(ii))
    2482         [ #  # ]:           0 :      rwg(:, ii) = 0.25_dp / E0
    2483                 :             :    end do
    2484                 :             : 
    2485                 :             :  ! e2=e3=e4
    2486         [ #  # ]:           0 :  else if (D23 + D34 < tol) then
    2487                 :           0 :    e10 = eig(2) - eig(1); inv_e10 = one / e10
    2488                 :             : 
    2489         [ #  # ]:           0 :    do iw=1,nw
    2490                 :             :      rwg(iw, 1) = &
    2491                 :             :        three * E0(iw)**2 * E1(iw) * inv_e10**4 * log(abs(E1(iw) / E0(iw))) &
    2492                 :           0 :        + 1.5_dp * E1(iw) * (two * E0(iw) + e10) * inv_e10**3 + inv_e10
    2493                 :             :    end do
    2494                 :             : 
    2495         [ #  # ]:           0 :    do iw=1,nw
    2496                 :             :      rwg(iw, 2) = &
    2497                 :             :        E0(iw) ** 3 * inv_e10**4 * log(abs(E0(iw) / E1(iw))) &
    2498                 :           0 :        - (six * E0(iw)**2 + three * E0(iw) * e10 + two * e10**2) * inv_e10**3 / six
    2499                 :             :    end do
    2500         [ #  # ]:           0 :    rwg(:,3) = rwg(:,2)
    2501         [ #  # ]:           0 :    rwg(:,4) = rwg(:,2)
    2502                 :             : 
    2503                 :             :    !rwg = zero
    2504                 :             : 
    2505                 :             :  ! e1=e2=e3
    2506         [ #  # ]:           0 :  else if (D12 + D23 < tol) then
    2507                 :             : 
    2508                 :           0 :    e30 = eig(4) - eig(1); inv_e30 = one / e30
    2509                 :             : 
    2510         [ #  # ]:           0 :    do iw=1,nw
    2511                 :             :      rwg(iw, 1) = &
    2512                 :             :        E3(iw)**3 * inv_e30**4 * log(abs(E3(iw) / E0(iw))) &
    2513                 :           0 :        + (six * E3(iw)**2 - three * E3(iw) * e30 + two * e30**2) * inv_e30**3 / six
    2514                 :             :    end do
    2515         [ #  # ]:           0 :    rwg(:,2) = rwg(:,1)
    2516         [ #  # ]:           0 :    rwg(:,3) = rwg(:,1)
    2517                 :             : 
    2518         [ #  # ]:           0 :    do iw=1,nw
    2519                 :             :      rwg(iw, 4) = &
    2520                 :             :        three * E0(iw) * E3(iw)**2 * inv_e30**4 * log(abs(E0(iw) / E3(iw))) &
    2521                 :           0 :        - 1.5_dp * E0(iw) * (two * E3(iw) - e30) * inv_e30**3 - inv_e30
    2522                 :             :    end do
    2523                 :             : 
    2524                 :             :    !rwg = zero
    2525                 :             : 
    2526                 :             :  ! e1=e2 < e3=e4
    2527         [ #  # ]:           0 :  else if (D12 + D34 < tol) then
    2528                 :             : 
    2529                 :           0 :    e20 = eig(3) - eig(1); inv_e20 = one / e20
    2530                 :             : 
    2531         [ #  # ]:           0 :    do iw=1,nw
    2532                 :             :      rwg(iw, 1) = &
    2533                 :             :        three * E0(iw) * E2(iw)**2 * inv_e20**4 * log(abs(E0(iw) / E2(iw))) &
    2534                 :           0 :        - 1.5_dp * E0(iw) * (two * E2(iw) - e20) * inv_e20**3 - inv_e20
    2535                 :             :    end do
    2536         [ #  # ]:           0 :    rwg(:,2) = rwg(:,1)
    2537                 :             : 
    2538         [ #  # ]:           0 :    do iw=1,nw
    2539                 :             :      rwg(iw, 3) = &
    2540                 :             :        three * E0(iw)** 2 * E2(iw) * inv_e20**4 * log(abs(E2(iw) / E0(iw))) &
    2541                 :           0 :        + 1.5_dp * E2(iw) * (two * E0(iw) + e20) * inv_e20**3 + inv_e20
    2542                 :             :    end do
    2543         [ #  # ]:           0 :    rwg(:,4) = rwg(:,3)
    2544                 :             : 
    2545                 :             :    !rwg = zero
    2546                 :             : 
    2547                 :             :  ! e3=e4
    2548         [ #  # ]:           0 :  else if (D34 < tol) then
    2549                 :             : 
    2550                 :           0 :    e10 = eig(2) - eig(1); inv_e10 = one / e10
    2551                 :           0 :    e20 = eig(3) - eig(1); inv_e20 = one / e20
    2552                 :           0 :    e21 = eig(3) - eig(2); inv_e21 = one / e21
    2553                 :             : 
    2554         [ #  # ]:           0 :    do iw=1,nw
    2555                 :             :      rwg(iw, 1) = &
    2556                 :             :        E0(iw)**2 * inv_e20**2 * inv_e10  &
    2557                 :             :        * (one + (-two * E2(iw) * inv_e20 - E1(iw) * inv_e10) * log(abs(E0(iw)))) &
    2558                 :             :        - E2(iw)**2 * inv_e20**2 * inv_e21 &
    2559                 :             :        * (one + (two * E0(iw) * inv_e20 + E1(iw) * inv_e21) * log(abs(E2(iw)))) &
    2560                 :           0 :        + E1(iw)**3 * inv_e10**2 * inv_e21**2 * log(abs(E1(iw)))
    2561                 :             :    end do
    2562                 :             : 
    2563         [ #  # ]:           0 :    do iw=1,nw
    2564                 :             :      rwg(iw, 2) = &
    2565                 :             :        -E1(iw)**2 * inv_e21**2 * inv_e10  &
    2566                 :             :        * (one + (-two * E2(iw) * inv_e21 + E0(iw) * inv_e10) * log(abs(E1(iw)))) &
    2567                 :             :        - E2(iw)**2 * inv_e21**2 * inv_e20 &
    2568                 :             :        * (one + (two * E1(iw) * inv_e21 + E0(iw) * inv_e20) * log(abs(E2(iw)))) &
    2569                 :           0 :        + E0(iw)**3 * inv_e10**2 * inv_e20**2 * log(abs(E0(iw)))
    2570                 :             :    end do
    2571                 :             : 
    2572         [ #  # ]:           0 :    do iw=1,nw
    2573                 :             :      rwg(iw, 3) = &
    2574                 :             :        +E0(iw)**3 * inv_e10 * inv_e20**3 * log(abs(E0(iw))) &
    2575                 :             :        -E1(iw)**3 * inv_e10 * inv_e21**3 * log(abs(E1(iw))) &
    2576                 :             :        +E2(iw) * inv_e20 * inv_e21 &
    2577                 :             :        * (half + E0(iw) * inv_e20 + E1(iw) * inv_e21  &
    2578                 :             :          +(E0(iw)**2 * inv_e20**2 + E1(iw)**2 * inv_e21**2 + &
    2579                 :           0 :            E0(iw) * E1(iw) * inv_e20 * inv_e21) * log(abs(E2(iw))))
    2580                 :             :    end do
    2581                 :             : 
    2582         [ #  # ]:           0 :    rwg(:,4) = rwg(:,3)
    2583                 :             : 
    2584                 :             :    !rwg = zero
    2585                 :             : 
    2586                 :             :  ! e2=e3
    2587         [ #  # ]:           0 :  else if (D23 < tol) then
    2588                 :             : 
    2589                 :           0 :    e10 = eig(2) - eig(1); inv_e10 = one / e10
    2590                 :           0 :    e30 = eig(4) - eig(1); inv_e30 = one / e30
    2591                 :           0 :    e31 = eig(4) - eig(2); inv_e31 = one / e31
    2592                 :             : 
    2593         [ #  # ]:           0 :    do iw=1,nw
    2594                 :             :      rwg(iw, 1) = &
    2595                 :             :        E0(iw)**2 * inv_e10**2 * inv_e30 &
    2596                 :             :        * (one - (two * E1(iw) * inv_e10 + E3(iw) * inv_e30) * log(abs(E0(iw)))) &
    2597                 :             :        + E1(iw)**2 * inv_e10**2 * inv_e31 &
    2598                 :             :        * (one + (+two * E0(iw) * inv_e10 - E3(iw) * inv_e31) * log(abs(E1(iw)))) &
    2599                 :           0 :        + E3(iw)**3 * inv_e30**2 * inv_e31**2 * log(abs(E3(iw)))
    2600                 :             :    end do
    2601                 :             : 
    2602         [ #  # ]:           0 :    do iw=1,nw
    2603                 :             :      rwg(iw, 2) = &
    2604                 :             :         E0(iw)**3 * inv_e30 * inv_e10**3 * log(abs(E0(iw))) &
    2605                 :             :        + E3(iw)**3 * inv_e30 * inv_e31**3 * log(abs(E3(iw))) &
    2606                 :             :        - E1(iw) * inv_e10 * inv_e31  &
    2607                 :             :        * (half + E0(iw) * inv_e10 - E3(iw) * inv_e31 + &
    2608                 :           0 :          (E0(iw)**2 * inv_e10**2 + E3(iw)**2 * inv_e31**2 - E0(iw) * E3(iw) * inv_e10 * inv_e31) * log(abs(E1(iw))))
    2609                 :             :    end do
    2610         [ #  # ]:           0 :    rwg(:,3) = rwg(:,2)
    2611                 :             : 
    2612         [ #  # ]:           0 :    do iw=1,nw
    2613                 :             :      rwg(iw, 4) = &
    2614                 :             :        -E3(iw)**2 * inv_e31**2 * inv_e30 &
    2615                 :             :        * (one + (two * E1(iw) * inv_e31 + E0(iw) * inv_e30) * log(abs(E3(iw)))) &
    2616                 :             :        - E1(iw)**2 * inv_e31**2 * inv_e10 &
    2617                 :             :        * (one + (-two * E3(iw) * inv_e31 + E0(iw) * inv_e10) * log(abs(E1(iw)))) &
    2618                 :           0 :        + E0(iw)**3 * inv_e30**2 * inv_e10**2 * log(abs(E0(iw)))
    2619                 :             :    end do
    2620                 :             : 
    2621                 :             :    !rwg = zero
    2622                 :             : 
    2623                 :             :  ! e1=e2
    2624         [ #  # ]:           0 :  else if (D12 < tol) then
    2625                 :             : 
    2626                 :           0 :    e20 = eig(3) - eig(1); inv_e20 = one / e20
    2627                 :           0 :    e30 = eig(4) - eig(1); inv_e30 = one / e30
    2628                 :           0 :    e32 = eig(4) - eig(3); inv_e32 = one / e32
    2629                 :             : 
    2630         [ #  # ]:           0 :    do iw=1,nw
    2631                 :             :      rwg(iw, 1) = &
    2632                 :             :         -E2(iw)**3 * inv_e32 * inv_e20**3 * log(abs(E2(iw))) &
    2633                 :             :        + E3(iw)**3 * inv_e32 * inv_e30**3 * log(abs(E3(iw))) &
    2634                 :             :        + E0(iw) * inv_e20 * inv_e30  &
    2635                 :             :        * (half - E2(iw) * inv_e20 - E3(iw) * inv_e30 + &
    2636                 :           0 :          (E2(iw)**2 * inv_e20**2 + E3(iw)**2 * inv_e30**2 + E2(iw) * E3(iw) * inv_e20 * inv_e30) * log(abs(E0(iw))))
    2637                 :             :    end do
    2638         [ #  # ]:           0 :    rwg(:,2) = rwg(:,1)
    2639                 :             : 
    2640         [ #  # ]:           0 :    do iw=1,nw
    2641                 :             :      rwg(iw, 3) = &
    2642                 :             :         E2(iw)**2 * inv_e20**2 * inv_e32 &
    2643                 :             :         * (one + (two * E0(iw) * inv_e20 - E3(iw) * inv_e32) * log(abs(E2(iw)))) &
    2644                 :             :         + E0(iw)**2 * inv_e20**2 * inv_e30 &
    2645                 :             :         * (one - (two * E2(iw) * inv_e20 + E3(iw) * inv_e30) * log(abs(E0(iw))))  &
    2646                 :           0 :         + (E3(iw)**3 * inv_e32**2 * inv_e30**2 * log(abs(E3(iw))))
    2647                 :             :    end do
    2648                 :             :    ! This was wrong due to a misplaced parantes
    2649                 :             :    !rwg(:,3) = zero
    2650                 :             : 
    2651         [ #  # ]:           0 :    do iw=1,nw
    2652                 :             :      rwg(iw, 4) = &
    2653                 :             :        -E3(iw)**2 * inv_e30**2 * inv_e32 &
    2654                 :             :        * (one + (two * E0(iw) * inv_e30 + E2(iw) * inv_e32) * log(abs(E3(iw)))) &
    2655                 :             :        + E0(iw)**2 * inv_e30**2 * inv_e20 &
    2656                 :             :        * (one - (two * E3(iw) * inv_e30 + E2(iw) * inv_e20) * log(abs(E0(iw)))) &
    2657                 :           0 :        + (E2(iw)**3 * inv_e32**2 * inv_e20**2 * log(abs(E2(iw))))
    2658                 :             :    end do
    2659                 :             : 
    2660                 :             :    !rwg = zero
    2661                 :             : 
    2662                 :             :  ! e1<e2<e3<e4
    2663                 :             :  else
    2664                 :             : 
    2665                 :           0 :    e10 = eig(2) - eig(1); inv_e10 = one / e10
    2666                 :           0 :    e20 = eig(3) - eig(1); inv_e20 = one / e20
    2667                 :           0 :    e21 = eig(3) - eig(2); inv_e21 = one / e21
    2668                 :           0 :    e30 = eig(4) - eig(1); inv_e30 = one / e30
    2669                 :           0 :    e31 = eig(4) - eig(2); inv_e31 = one / e31
    2670                 :           0 :    e32 = eig(4) - eig(3); inv_e32 = one / e32
    2671                 :             : 
    2672         [ #  # ]:           0 :    do iw=1,nw
    2673                 :             :      rwg(iw, 1) = &
    2674                 :             :        E0(iw)**2 * inv_e10 * inv_e20 * inv_e30 &
    2675                 :             :        * (one - (E1(iw) * inv_e10 + E2(iw) * inv_e20 + E3(iw) * inv_e30) * log(abs(E0(iw)))) &
    2676                 :             :        + E1(iw)**3 * inv_e10**2 * inv_e21 * inv_e31 * log(abs(E1(iw))) &
    2677                 :             :        - E2(iw)**3 * inv_e20**2 * inv_e21 * inv_e32 * log(abs(E2(iw))) &
    2678                 :           0 :        + E3(iw)**3 * inv_e30**2 * inv_e31 * inv_e32 * log(abs(E3(iw)))
    2679                 :             :    end do
    2680                 :             : 
    2681         [ #  # ]:           0 :    do iw=1,nw
    2682                 :             :      rwg(iw, 2) = &
    2683                 :             :        -E1(iw)**2 * inv_e10 * inv_e21 * inv_e31 &
    2684                 :             :        * (one + (E0(iw) * inv_e10 - E2(iw) * inv_e21 - E3(iw) * inv_e31) * log(abs(E1(iw)))) &
    2685                 :             :        + E0(iw)**3 * inv_e10**2 * inv_e20 * inv_e30 * log(abs(E0(iw))) &
    2686                 :             :        - E2(iw)**3 * inv_e20 * inv_e21**2 * inv_e32 * log(abs(E2(iw))) &
    2687                 :           0 :        + E3(iw)**3 * inv_e30 * inv_e31**2 * inv_e32 * log(abs(E3(iw)))
    2688                 :             :    end do
    2689                 :             : 
    2690         [ #  # ]:           0 :    do iw=1,nw
    2691                 :             :      rwg(iw, 3) = &
    2692                 :             :        E2(iw)**2 * inv_e20 * inv_e21 * inv_e32 &
    2693                 :             :        * (one + (E0(iw) * inv_e20 + E1(iw) * inv_e21 - E3(iw) * inv_e32) * log(abs(E2(iw)))) &
    2694                 :             :        + E0(iw)**3 * inv_e10 * inv_e20**2 * inv_e30 * log(abs(E0(iw))) &
    2695                 :             :        - E1(iw)**3 * inv_e10 * inv_e21**2 * inv_e31 * log(abs(E1(iw))) &
    2696                 :           0 :        + E3(iw)**3 * inv_e30 * inv_e31 * inv_e32**2 * log(abs(E3(iw)))
    2697                 :             :    end do
    2698                 :             : 
    2699         [ #  # ]:           0 :    do iw=1,nw
    2700                 :             :      rwg(iw, 4) = &
    2701                 :             :        -E3(iw)**2 * inv_e30 * inv_e31 * inv_e32 &
    2702                 :             :        * (one + (E0(iw) * inv_e30 + E1(iw) * inv_e31 + E2(iw) * inv_e32) * log(abs(E3(iw)))) &
    2703                 :             :        + E0(iw)**3 * inv_e10 * inv_e20 * inv_e30**2 * log(abs(E0(iw))) &
    2704                 :             :        - E1(iw)**3 * inv_e10 * inv_e21 * inv_e31**2 * log(abs(E1(iw))) &
    2705                 :           0 :        + E2(iw)**3 * inv_e20 * inv_e21 * inv_e32**2 * log(abs(E2(iw)))
    2706                 :             :    end do
    2707                 :             :    !rwg = zero
    2708                 :             : 
    2709                 :             :  end if
    2710                 :             : 
    2711                 :           0 : end subroutine get_onetetra_ppart_lv
    2712                 :             : !!***
    2713                 :             : 
    2714   [ -  +  -  -  :         729 : end module m_htetra
          +  +  -  +  +  
          -  -  +  -  +  
          +  -  -  +  -  
          +  -  -  -  -  
          -  +  -  +  -  
             -  -  -  -  
                      + ]
    2715                 :             : !!***
        

Generated by: LCOV version 2.3-1