LCOV - code coverage report
Current view: top level - src/77_ddb - defs_elphon.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 88.1 % 319 281
Test Date: 2026-09-21 22:40:37 Functions: 93.3 % 15 14

            Line data    Source code
       1              : !!****m* ABINIT/defs_elphon
       2              : !!
       3              : !! NAME
       4              : !! defs_elphon
       5              : !!
       6              : !! FUNCTION
       7              : !! This module contains the datastructures for elphon
       8              : !!  the different (huge) matrices will either be allocated and
       9              : !!  used, or be written to disk. All combinations should be feasible.
      10              : !!
      11              : !! COPYRIGHT
      12              : !! Copyright (C) 2004-2026 ABINIT group (MVer, MG)
      13              : !! This file is distributed under the terms of the
      14              : !! GNU General Public Licence, see ~abinit/COPYING
      15              : !! or http://www.gnu.org/copyleft/gpl.txt .
      16              : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt .
      17              : !!
      18              : !! NOTES
      19              : !!  Contains the following datastructures:
      20              : !!   1) elph_type contains data and dimensions for the kpoints near the
      21              : !!      fermi surface and the $g_{k k+q}$ matrix elements
      22              : !!
      23              : !! SOURCE
      24              : 
      25              : #if defined HAVE_CONFIG_H
      26              : #include "config.h"
      27              : #endif
      28              : 
      29              : #include "abi_common.h"
      30              : 
      31              : module defs_elphon
      32              : 
      33              :  use defs_basis
      34              :  use m_abicore
      35              :  use m_errors
      36              :  use m_xmpi
      37              :  use m_krank
      38              :  use m_crystal
      39              : 
      40              :  implicit none
      41              : 
      42              :  private
      43              : !!***
      44              : 
      45              :  public :: gam_mult_displ
      46              :  public :: complete_gamma
      47              :  public :: complete_gamma_tr
      48              :  public :: mkqptequiv
      49              : 
      50              : !----------------------------------------------------------------------
      51              : !!****t* defs_elphon/elph_kgrid_type
      52              : !! NAME
      53              : !! elph_kgrid_type
      54              : !!
      55              : !! FUNCTION
      56              : !! elph_kgrid_type contains k-point grid data and dimensions
      57              : !!  this is a sub object of elph_type
      58              : !!
      59              : !! SOURCE
      60              : 
      61              :   type,public :: elph_kgrid_type
      62              : 
      63              :    integer :: nband                           ! number of bands for weights
      64              :    integer :: nsppol                          ! number of spin pol for weights
      65              :    integer :: nsym                            ! number of symmetry operations
      66              :    integer :: nkpt                            ! number of k-points in full grid
      67              :    integer :: nkptirr                         ! number of k-points in irreducible grid
      68              :    integer :: new_nkptirr                     ! number of k-points in irreducible grid
      69              :    integer :: my_nkpt                         ! number of k-points on present processor
      70              : 
      71              :    type(krank_t) :: krank            ! ranking of all kpoints on phonon calculation grid, and inverse rank
      72              : 
      73              :    integer, allocatable :: irr2full(:)            ! correspondence of irred kpoints to a full one
      74              :    integer, allocatable :: full2irr(:,:)          ! correspondence of full k to one irred kpoints through sym and timrev
      75              :    integer, allocatable :: full2full(:,:,:)       ! symmetry mapping of kpoints
      76              :    integer, allocatable :: my_kpt(:)              ! flag for k-points belonging to present proc (= me index of proc for each k-point)
      77              :    integer, allocatable :: my_ikpt(:)             ! flag for k-points belonging to present proc (= me index of proc for each k-point)
      78              :    integer, allocatable :: irredtoGS(:)           ! (nkptirr)
      79              :    integer, allocatable :: new_irredtoGS(:)       ! (new_nkptirr)
      80              : 
      81              :    real(dp),allocatable :: kpt(:,:)               ! coordinates of the full kpoints from phonon calculation
      82              :    real(dp),allocatable :: kptirr(:,:)            ! irreducible k-points, for preliminary set up
      83              :    real(dp),allocatable :: new_kptirr(:,:)        ! irreducible k-points, for preliminary set up
      84              :    real(dp),allocatable :: wtk(:,:,:)             ! integration weights (see also gkk_intweight)
      85              :    real(dp),allocatable :: wtq(:,:,:)             ! integration weights (see also gkk_intweight)
      86              :    real(dp),allocatable :: wtkirr(:)              ! weights for irreducible kpoints, to sum over _whole_ BZ (not just Fermi Surface)
      87              :    real(dp),allocatable :: new_wtkirr(:)          ! weights for irreducible kpoints, to sum over _whole_ BZ (not just Fermi Surface)
      88              :    real(dp),allocatable :: velocwtk(:,:,:,:)      ! (nFSband,nkpt_fine,3,nsppol), v(k)*wtk
      89              :    real(dp),allocatable :: vvelocwtk(:,:,:,:,:)   ! (nFSband,nkpt_fine,3,3,nsppol), v(k)*v(k)*wtk
      90              : 
      91              :   end type elph_kgrid_type
      92              : 
      93              :   public :: elph_k_copy
      94              :   public :: elph_k_procs
      95              :   public :: elph_k_destroy
      96              : !!***
      97              : 
      98              : !----------------------------------------------------------------------
      99              : 
     100              : !!****t* defs_elphon/elph_type
     101              : !! NAME
     102              : !! elph_type
     103              : !!
     104              : !! FUNCTION
     105              : !! elph_type contains data and dimensions for the kpoints near the
     106              : !! fermi surface and the $g_{k k+q}$ matrix elements
     107              : !!
     108              : !! SOURCE
     109              : 
     110              :   type,public :: elph_type
     111              : 
     112              :    type(elph_kgrid_type) :: k_phon               ! object for k-grid of phonon calculation
     113              :    type(elph_kgrid_type) :: k_fine               ! object for fine k-grid for FS integration
     114              : 
     115              :    integer :: natom,nbranch,nFSband,nband
     116              :    integer :: minFSband,maxFSband                !Index of lower and upper bands used for the FS integration
     117              : 
     118              :    integer :: ngkkband                           !Number of bands kept in final gkk matrix elements:
     119              :                                                  !either 1 if sum is performed immediately
     120              :                                                  !or = nband if all elements are kept based on flag ep_keepbands
     121              : 
     122              :    integer :: nenergy                            ! number of points in energy
     123              :                                                  !   space for the electron band energies
     124              :                                                  !   energies from
     125              :                                                  !   ef-nenergy*delta_e to
     126              :                                                  !   ef+nenergy*delta_e
     127              : 
     128              :    integer :: n_pair                             ! number of pairs considered
     129              : 
     130              :    integer :: nqpt_full                          !number of q in full BZ
     131              :    integer :: nqptirred                          !number of irred q-points
     132              : 
     133              : 
     134              :    integer :: unita2f,unit_gkk2,unit_gkk_rpt
     135              :    integer :: unitgkq                            !units for file output
     136              : 
     137              :    integer :: gkqwrite
     138              :    integer :: gkk2write
     139              :    integer :: gkk_rptwrite
     140              : 
     141              :    integer :: ep_scalprod                        !flag to perform the scalar product
     142              :    integer :: symgkq                             !flag to symmetrize gkq matrix elements
     143              :    integer :: ep_keepbands                       !flag to sum over bands or not
     144              :    integer :: ep_lova                            ! 1 for lova, and 0 for general
     145              :    integer :: tuniformgrid                       !flag to expect uniform grid of q or not
     146              :    integer :: prtbltztrp                         !flag to output BoltzTraP input files
     147              : 
     148              :    integer :: na2f                               !dimensions and increments for a2F function
     149              :    integer :: nsppol                             ! number of spin polarization channels
     150              :    integer :: nspinor                            ! number of spinorial components
     151              :    integer :: telphint                           ! flag for integration over the FS with 0=tetrahedra 1=gaussians
     152              :    integer :: ep_nspline                         ! scale factor for spline interpolation in RTA
     153              :    integer :: ntemper                            ! number of temperature points
     154              :    integer :: use_k_fine                         ! flag for using fine k-grids for eigenvalues and velocities. 0=no 1=yes
     155              :    integer :: ep_int_gkk                         ! flag for interpolate gkk(1) or gamma (0)
     156              :    integer :: ep_b_min                           ! first band taken into account in FS integration (if telphint==2)
     157              :    integer :: ep_b_max                           ! last band taken into account in FS integration (if telphint==2)
     158              :    integer :: kptrlatt(3,3)                      ! kpoint grid generating vectors, as in abinit
     159              :    integer :: kptrlatt_fine(3,3)                 ! kpoint grid generating vectors, for fine grid used in FS integration
     160              : 
     161              :    real(dp) :: delta_e                           ! step in electronic energies, around Fermi level
     162              :    real(dp) :: omega_min,omega_max
     163              :    real(dp) :: a2fsmear,domega
     164              :    real(dp) :: nelect                            ! number of electrons per unit cell, eventually with extra charges for carriers in semiconductors.
     165              :    real(dp) :: occ_factor                        ! normalization for integrals over FS, for num of spins, spinors, etc...
     166              : 
     167              :    real(dp) :: mustar                            ! mustar parameter
     168              :    real(dp) :: fermie                            ! Fermi energy (Ha), either comes from wfk file or from anaddb input file
     169              :    real(dp) :: elphsmear                         ! smearing width for gaussian integration or buffer in energy for
     170              :                                                  ! calculations with tetrahedra (telphint=0)
     171              :    real(dp) :: tempermin                         ! minimum temperature at which resistivity etc are calculated (in K)
     172              :    real(dp) :: temperinc                         ! interval temperature grid on which resistivity etc are calculated (in K)
     173              : 
     174              :    character(len=fnlen) :: elph_base_name        !base name for output files
     175              : 
     176              :    integer,allocatable :: qirredtofull(:)            !mapping between the qpoints found in the GGK file
     177              :                                                  !and the array of qpoints generated by the code
     178              : 
     179              :    real(dp),allocatable :: wtq(:)                    !weight for each qpoint in the full grid spqt
     180              :                                                  !if a point is not in the IBZ ==>  wtq=0
     181              :                                                  !MG we can also use indqpt
     182              : 
     183              :    real(dp),allocatable :: n0(:)                     !DOS at the Fermi level (states/Ha/spin)
     184              :    real(dp),allocatable :: qpt_full(:,:)             !special q points obtained by the Monkhorst & Pack method,
     185              :                                                  !in reduced coordinates
     186              : 
     187              : 
     188              :    real(dp),allocatable :: gkk_intweight(:,:,:)      ! (nFSband,nkpt_fine,nsppol)
     189              :                                                  !integration weights for gkk matrix elements on FS:
     190              :                                                  !if ep_keepbands == 0 all are 1
     191              :                                                  !if ep_keepbands == 1 then = to wtk_phon in elphon
     192              :                                                  !DOES NOT INCLUDE FACTOR OF 1/nkpt_phon
     193              : 
     194              :    real(dp),allocatable :: gkk_velocwtk(:,:,:)      ! (nFSband,nkpt_fine,nsppol)
     195              : 
     196              :    real(dp),allocatable :: gkk_vvelocwtk(:,:,:)      ! (nFSband,nkpt_fine,nsppol)
     197              : 
     198              :    real(dp),allocatable :: gkk_qpt(:,:,:,:,:,:)      ! (2, ngkkband*ngkkband, nbranch*nbranch, nkpt_phon, nsppol, nqptirred)
     199              :                                                  !Now gkq contains gkk2 matrices on basic qpts,
     200              :                                                  !summed over bands if ngkkband==1
     201              : 
     202              : 
     203              :    real(dp),allocatable :: gkk_rpt(:,:,:,:,:,:)      ! (2, ngkkband**2, nbranch**2, nkpt_phon, nsppol, nrpt)
     204              :                                                  !For the moment, gkk_rpt in memory is out of the question
     205              :    real(dp),allocatable :: gkk2(:,:,:,:,:,:)         ! (nbranch, ngkkband,ngkkband, nkpt_phon, nkpt_phon, nsppol)
     206              : 
     207              :    real(dp),allocatable :: gamma_qpt(:,:,:,:)        !gamma matrices integrated over kpoint coeff
     208              :                                                  !  and bands: still depends on qpt
     209              :                                                  ! dims= 2, nbranch**2, nsppol, nqpt
     210              :    real(dp),allocatable :: gamma_rpt(:,:,:,:)
     211              :                                                  ! dims= 2, nbranch**2, nsppol, nrpt
     212              : !NOTE: choice to put nsppol before or after nqpt is a bit arbitrary
     213              : !   abinit uses nband,nkpt,nsppol, but here for convenience nkpt_phon,nsppol,nqpt
     214              : !   as interpolation is on qpt
     215              : 
     216              :    real(dp),allocatable :: phfrq(:,:)                !phonon frequencies
     217              :    real(dp),allocatable :: a2f(:,:,:)                !a2f function
     218              : 
     219              :    real(dp),allocatable :: qgrid_data(:,:,:,:)       !e-ph values calculated over the irreducible part of the q-grid:
     220              :                                                  !first entry  =  index of the q-point,
     221              :                                                  !second index =  branch index
     222              :                                                  !the third slice contains the frequency, the linewidth and lambda(q,nu)
     223              :                                                  !for that particular phonon mode
     224              :                                                  ! dims= nqptirred,elph_ds%nbranch,nsppol,3
     225              : 
     226              :  end type elph_type
     227              : 
     228              :  public :: elph_ds_clean
     229              : !!***
     230              : 
     231              : !----------------------------------------------------------------------
     232              : 
     233              : !!****t* defs_elphon/elph_tr_type
     234              : !! NAME
     235              : !! elph_tr_type
     236              : !!
     237              : !! FUNCTION
     238              : !! elph_tr_ds contains the necessary data for the transport properties
     239              : !!
     240              : !! SOURCE
     241              : 
     242              :   type,public :: elph_tr_type
     243              : 
     244              :      integer :: ifltransport
     245              :      integer :: unitgkq_trin,unitgkq_trout
     246              :      integer :: gkqwrite,gkqexist
     247              :      integer :: onegkksize
     248              : 
     249              :      character(len=fnlen) :: ddkfilename
     250              : 
     251              :      real(dp),allocatable :: dos_n0(:,:)                  ! (nT,nsppol) DOS at the Fermi level (states/Ha/spin) at input temperatures
     252              :      real(dp),allocatable :: dos_n(:,:)                   ! (nE,nsppol) DOS at the selected energies (states/Ha/spin)
     253              :      real(dp),allocatable :: en_all(:,:)                  ! (nE,nsppol) selected energies
     254              :      real(dp),allocatable :: de_all(:,:)                  ! (nE,nsppol) differences between selected energies
     255              :      real(dp),allocatable :: veloc_sq0(:,:,:)             ! (3,nsppol,nT)
     256              :      real(dp),allocatable :: veloc_sq(:,:,:)              ! (3,nsppol,nE)
     257              : 
     258              :      real(dp),allocatable :: el_veloc(:,:,:,:)        ! nkpt nband 3 nsppol
     259              : ! the 9 = 3x3 is for the full tensorial transport coefficients
     260              :      real(dp),allocatable :: gamma_qpt_tr(:,:,:,:,:)    ! 2 9 branches**2 nsppol qpt
     261              :      real(dp),allocatable :: gamma_qpt_trin(:,:,:,:,:)  !idem
     262              :      real(dp),allocatable :: gamma_qpt_trout(:,:,:,:,:) !idem
     263              : 
     264              :      real(dp),allocatable :: gamma_rpt_tr(:,:,:,:,:,:,:)    !idem
     265              :      real(dp),allocatable :: gamma_rpt_trin(:,:,:,:,:)  !idem
     266              :      real(dp),allocatable :: gamma_rpt_trout(:,:,:,:,:) !idem
     267              : 
     268              :      real(dp),allocatable :: a2f_1d_tr(:,:,:,:,:,:)           ! nfreq 9 nsppol 4 n_pair ntemp
     269              :      real(dp),allocatable :: a2f_1d_trin(:,:,:)
     270              :      real(dp),allocatable :: a2f_1d_trout(:,:,:)
     271              : 
     272              :      real(dp),allocatable :: FSelecveloc_sq(:,:)       ! 3 nsppol
     273              : 
     274              :      real(dp),allocatable :: tmp_gkk_intweight(:,:,:,:)
     275              :      real(dp),allocatable :: tmp_gkk_intweight1(:,:,:)
     276              :      real(dp),allocatable :: tmp_gkk_intweight2(:,:,:)
     277              : 
     278              :      real(dp),allocatable :: tmp_velocwtk(:,:,:,:,:)
     279              :      real(dp),allocatable :: tmp_velocwtk1(:,:,:,:)
     280              :      real(dp),allocatable :: tmp_velocwtk2(:,:,:,:)
     281              : 
     282              :      real(dp),allocatable :: tmp_vvelocwtk(:,:,:,:,:,:)
     283              :      real(dp),allocatable :: tmp_vvelocwtk1(:,:,:,:,:)
     284              :      real(dp),allocatable :: tmp_vvelocwtk2(:,:,:,:,:)
     285              : 
     286              :   end type elph_tr_type
     287              : 
     288              :  public :: elph_tr_ds_clean
     289              : !!***
     290              : 
     291              : !----------------------------------------------------------------------
     292              : 
     293              : CONTAINS
     294              : !!***
     295              : 
     296              : !----------------------------------------------------------------------
     297              : 
     298              : !!****f* defs_elphon/elph_ds_clean
     299              : !!
     300              : !! NAME
     301              : !!   elph_ds_clean
     302              : !!
     303              : !! FUNCTION
     304              : !!   deallocate remaining arrays in the elph_ds datastructure
     305              : !!
     306              : !! INPUTS
     307              : !!  elph_ds = elphon datastructure
     308              : !!
     309              : !! SOURCE
     310              : 
     311           15 : subroutine elph_ds_clean(elph_ds)
     312              : 
     313              : !Arguments ------------------------------------
     314              :  class(elph_type), intent(inout) :: elph_ds
     315              : ! *************************************************************************
     316              : 
     317              :  !@elph_type
     318           15 :  ABI_SFREE(elph_ds%qirredtofull)
     319           15 :  ABI_SFREE(elph_ds%wtq)
     320           15 :  ABI_SFREE(elph_ds%n0)
     321           15 :  ABI_SFREE(elph_ds%qpt_full)
     322           15 :  ABI_SFREE(elph_ds%gkk_intweight)
     323           15 :  ABI_SFREE(elph_ds%gkk_qpt)
     324           15 :  ABI_SFREE(elph_ds%gkk_rpt)
     325           15 :  ABI_SFREE(elph_ds%gkk2)
     326           15 :  ABI_SFREE(elph_ds%gamma_qpt)
     327           15 :  ABI_SFREE(elph_ds%gamma_rpt)
     328           15 :  ABI_SFREE(elph_ds%phfrq)
     329           15 :  ABI_SFREE(elph_ds%a2f)
     330           15 :  ABI_SFREE(elph_ds%qgrid_data)
     331              : 
     332           15 :  call elph_k_destroy (elph_ds%k_phon)
     333           15 :  call elph_k_destroy (elph_ds%k_fine)
     334              : 
     335           15 :  call elph_ds%k_fine%krank%free()
     336              : 
     337           15 : end subroutine elph_ds_clean
     338              : !!***
     339              : 
     340              : !----------------------------------------------------------------------
     341              : 
     342              : !!****f* defs_elphon/elph_tr_ds_clean
     343              : !!
     344              : !! NAME
     345              : !!   elph_tr_ds_clean
     346              : !!
     347              : !! FUNCTION
     348              : !!   deallocate remaining arrays in the elph_tr_ds datastructure
     349              : !!
     350              : !! INPUTS
     351              : !!  elph_tr_ds = elphon transport datastructure
     352              : !!
     353              : !! SOURCE
     354              : 
     355           15 : subroutine elph_tr_ds_clean(elph_tr_ds)
     356              : 
     357              : !Arguments ------------------------------------
     358              :  class(elph_tr_type), intent(inout) :: elph_tr_ds
     359              : ! *************************************************************************
     360              : 
     361              :  !@elph_tr_type
     362           15 :  ABI_SFREE(elph_tr_ds%el_veloc)
     363           15 :  ABI_SFREE(elph_tr_ds%FSelecveloc_sq)
     364           15 :  ABI_SFREE(elph_tr_ds%veloc_sq0)
     365           15 :  ABI_SFREE(elph_tr_ds%veloc_sq)
     366           15 :  ABI_SFREE(elph_tr_ds%dos_n0)
     367           15 :  ABI_SFREE(elph_tr_ds%dos_n)
     368           15 :  ABI_SFREE(elph_tr_ds%en_all)
     369           15 :  ABI_SFREE(elph_tr_ds%de_all)
     370           15 :  ABI_SFREE(elph_tr_ds%gamma_qpt_tr)
     371           15 :  ABI_SFREE(elph_tr_ds%gamma_qpt_trin)
     372           15 :  ABI_SFREE(elph_tr_ds%gamma_qpt_trout)
     373           15 :  ABI_SFREE(elph_tr_ds%gamma_rpt_tr)
     374           15 :  ABI_SFREE(elph_tr_ds%gamma_rpt_trin)
     375           15 :  ABI_SFREE(elph_tr_ds%gamma_rpt_trout)
     376           15 :  ABI_SFREE(elph_tr_ds%a2f_1d_tr)
     377           15 :  ABI_SFREE(elph_tr_ds%a2f_1d_trin)
     378           15 :  ABI_SFREE(elph_tr_ds%a2f_1d_trout)
     379           15 :  ABI_SFREE(elph_tr_ds%tmp_gkk_intweight)
     380           15 :  ABI_SFREE(elph_tr_ds%tmp_gkk_intweight1)
     381           15 :  ABI_SFREE(elph_tr_ds%tmp_gkk_intweight2)
     382           15 :  ABI_SFREE(elph_tr_ds%tmp_velocwtk)
     383           15 :  ABI_SFREE(elph_tr_ds%tmp_velocwtk1)
     384           15 :  ABI_SFREE(elph_tr_ds%tmp_velocwtk2)
     385           15 :  ABI_SFREE(elph_tr_ds%tmp_vvelocwtk)
     386           15 :  ABI_SFREE(elph_tr_ds%tmp_vvelocwtk1)
     387           15 :  ABI_SFREE(elph_tr_ds%tmp_vvelocwtk2)
     388              : 
     389           15 : end subroutine elph_tr_ds_clean
     390              : !!***
     391              : 
     392              : !----------------------------------------------------------------------
     393              : 
     394              : !!****f* defs_elphon/elph_k_copy
     395              : !!
     396              : !! NAME
     397              : !!   elph_k_copy
     398              : !!
     399              : !! FUNCTION
     400              : !!   allocate and copy arrays in the elph_k datastructure
     401              : !!
     402              : !! INPUTS
     403              : !!  elph_k = elphon k-points datastructure
     404              : !!
     405              : !! NOTES
     406              : !!
     407              : !! SOURCE
     408              : 
     409            0 : subroutine elph_k_copy(elph_k_in, elph_k_out)
     410              : 
     411              : !Arguments ------------------------------------
     412              :  class(elph_kgrid_type), intent(in) :: elph_k_in
     413              :  class(elph_kgrid_type), intent(out) :: elph_k_out
     414              : ! *************************************************************************
     415              : 
     416              :  !@elph_kgrid_type
     417            0 :  elph_k_out%nband = elph_k_in%nband
     418            0 :  elph_k_out%nsppol = elph_k_in%nsppol
     419            0 :  elph_k_out%nsym = elph_k_in%nsym
     420              : 
     421            0 :  elph_k_out%nkpt = elph_k_in%nkpt
     422            0 :  elph_k_out%nkptirr = elph_k_in%nkptirr
     423              : 
     424            0 :  elph_k_out%my_nkpt = elph_k_in%my_nkpt
     425              : 
     426            0 :  ABI_MALLOC(elph_k_out%my_kpt,(elph_k_out%nkpt))
     427            0 :  elph_k_out%my_kpt = elph_k_in%my_kpt
     428              : 
     429            0 :  ABI_MALLOC(elph_k_out%my_ikpt,(elph_k_out%my_nkpt))
     430            0 :  elph_k_out%my_ikpt = elph_k_in%my_ikpt
     431              : 
     432            0 :  ABI_MALLOC(elph_k_out%kptirr,(3,elph_k_out%nkptirr))
     433            0 :  elph_k_out%kptirr = elph_k_in%kptirr
     434            0 :  ABI_MALLOC(elph_k_out%wtkirr,(elph_k_out%nkptirr))
     435            0 :  elph_k_out%wtkirr = elph_k_in%wtkirr
     436              : 
     437            0 :  ABI_MALLOC(elph_k_out%wtk,(elph_k_out%nband,elph_k_out%nkpt,elph_k_out%nsppol))
     438            0 :  elph_k_out%wtk = elph_k_in%wtk
     439            0 :  ABI_MALLOC(elph_k_out%kpt,(3,elph_k_out%nkpt))
     440            0 :  elph_k_out%kpt = elph_k_in%kpt
     441              : 
     442            0 :  elph_k_out%krank = elph_k_in%krank%copy()
     443              : 
     444            0 :  ABI_MALLOC(elph_k_out%irr2full,(elph_k_out%nkptirr))
     445            0 :  elph_k_out%irr2full = elph_k_in%irr2full
     446            0 :  ABI_MALLOC(elph_k_out%full2irr,(3,elph_k_out%nkpt))
     447            0 :  elph_k_out%full2irr = elph_k_in%full2irr
     448            0 :  ABI_MALLOC(elph_k_out%full2full,(2,elph_k_out%nsym,elph_k_out%nkpt))
     449            0 :  elph_k_out%full2full = elph_k_in%full2full
     450              : 
     451            0 :  ABI_MALLOC(elph_k_out%irredtoGS,(elph_k_out%nkptirr))
     452            0 :  elph_k_out%irredtoGS = elph_k_in%irredtoGS
     453              : 
     454            0 : end subroutine elph_k_copy
     455              : !!***
     456              : 
     457              : !----------------------------------------------------------------------
     458              : 
     459              : !!****f* defs_elphon/elph_k_destroy
     460              : !!
     461              : !! NAME
     462              : !!   elph_k_destroy
     463              : !!
     464              : !! FUNCTION
     465              : !!   deallocate arrays in the elph_k datastructure
     466              : !!
     467              : !! INPUTS
     468              : !!  elph_k = elphon k-points datastructure
     469              : !!
     470              : !! SOURCE
     471              : 
     472           30 : subroutine elph_k_destroy(elph_k)
     473              : 
     474              : !Arguments ------------------------------------
     475              :  class(elph_kgrid_type), intent(inout) :: elph_k
     476              : ! *************************************************************************
     477              : 
     478              :  !@elph_kgrid_type
     479           30 :  ABI_SFREE(elph_k%irr2full)
     480           30 :  ABI_SFREE(elph_k%full2irr)
     481           30 :  ABI_SFREE(elph_k%full2full)
     482           30 :  ABI_SFREE(elph_k%irredtoGS)
     483           30 :  ABI_SFREE(elph_k%new_irredtoGS)
     484           30 :  ABI_SFREE(elph_k%kpt)
     485           30 :  ABI_SFREE(elph_k%kptirr)
     486           30 :  ABI_SFREE(elph_k%new_kptirr)
     487           30 :  ABI_SFREE(elph_k%my_kpt)
     488           30 :  ABI_SFREE(elph_k%my_ikpt)
     489           30 :  ABI_SFREE(elph_k%wtk)
     490           30 :  ABI_SFREE(elph_k%wtq)
     491           30 :  ABI_SFREE(elph_k%wtkirr)
     492           30 :  ABI_SFREE(elph_k%new_wtkirr)
     493           30 :  ABI_SFREE(elph_k%velocwtk)
     494           30 :  ABI_SFREE(elph_k%vvelocwtk)
     495              : 
     496           30 :  call elph_k%krank%free()
     497              : 
     498           30 : end subroutine elph_k_destroy
     499              : !!***
     500              : 
     501              : !----------------------------------------------------------------------
     502              : 
     503              : !!****f* defs_elphon/elph_k_procs
     504              : !!
     505              : !! NAME
     506              : !!   elph_k_procs
     507              : !!
     508              : !! FUNCTION
     509              : !!   allocate kpt to processors, in the elph_k datastructure
     510              : !!
     511              : !! INPUTS
     512              : !!  nproc = number of k-parallel processors
     513              : !!  elph_k = elphon k-points datastructure
     514              : !!
     515              : !! NOTES
     516              : !!
     517              : !! SOURCE
     518              : 
     519           15 : subroutine elph_k_procs(nproc, elph_k)
     520              : 
     521              : !Arguments ------------------------------------
     522              : !scalars
     523              :  integer, intent(in) :: nproc
     524              :  class(elph_kgrid_type), intent(inout) :: elph_k
     525              : 
     526              :  integer :: ikpt, me, ik_this_proc
     527              : ! *************************************************************************
     528              : 
     529           15 :  ABI_SFREE (elph_k%my_kpt)
     530           45 :  ABI_MALLOC (elph_k%my_kpt, (elph_k%nkpt))
     531              : 
     532         1327 :  elph_k%my_kpt = 0
     533           15 :  elph_k%my_nkpt = 0
     534           15 :  me = xmpi_comm_rank(xmpi_world)
     535         1327 :  do ikpt = 1, elph_k%nkpt
     536         1312 :    elph_k%my_kpt(ikpt) = MOD(ikpt-1, nproc)
     537         1327 :    if (elph_k%my_kpt(ikpt) == me) elph_k%my_nkpt = elph_k%my_nkpt + 1
     538              :  end do
     539              : 
     540              : ! create inverse mapping from ik_this_proc to ikpt
     541           15 :  ABI_SFREE (elph_k%my_ikpt)
     542           45 :  ABI_MALLOC (elph_k%my_ikpt, (elph_k%my_nkpt))
     543         1327 :  elph_k%my_ikpt = 0
     544              : 
     545           15 :  ik_this_proc = 0
     546         1327 :  do ikpt = 1, elph_k%nkpt
     547         1327 :    if (elph_k%my_kpt(ikpt) == me) then
     548         1312 :      ik_this_proc = ik_this_proc + 1
     549         1312 :      elph_k%my_ikpt(ik_this_proc) = ikpt
     550              :    end if
     551              :  end do
     552           15 :  ABI_CHECK(ik_this_proc == elph_k%my_nkpt, 'found inconsistent k distribution in processors')
     553              : 
     554           15 :  write (std_out,*) 'elph_k_procs : nkpt, distrib = ', elph_k%my_nkpt
     555           15 :  write (std_out,*) elph_k%my_kpt
     556           15 :  write (std_out,*) elph_k%my_ikpt
     557              : 
     558           15 : end subroutine elph_k_procs
     559              : !!***
     560              : 
     561              : !----------------------------------------------------------------------
     562              : 
     563              : !!****f* defs_elphon/gam_mult_displ
     564              : !!
     565              : !! NAME
     566              : !! gam_mult_displ
     567              : !!
     568              : !! FUNCTION
     569              : !! This routine takes the bare gamma matrices and multiplies them
     570              : !!  by the displ_red matrices (related to the scalprod variable)
     571              : !!
     572              : !! INPUTS
     573              : !!   nbranch = number of phonon branches (3*natom)
     574              : !!   displ_red = phonon mode displacement vectors in reduced coordinates.
     575              : !!   gam_bare = bare gamma matrices before multiplication
     576              : !!
     577              : !! OUTPUT
     578              : !!   gam_now = output gamma matrices multiplied by displacement matrices
     579              : !!
     580              : !! SOURCE
     581              : 
     582        48368 : subroutine gam_mult_displ(nbranch, displ_red, gam_bare, gam_now)
     583              : 
     584              : !Arguments -------------------------------
     585              :  integer, intent(in)  :: nbranch
     586              :  real(dp), intent(in)  :: displ_red(2,nbranch,nbranch)
     587              :  real(dp), intent(in)  :: gam_bare(2,nbranch,nbranch)
     588              :  real(dp), intent(out) :: gam_now(2,nbranch,nbranch)
     589              : 
     590              : !Local variables -------------------------
     591        48368 :  real(dp) :: zgemm_tmp_mat(2,nbranch,nbranch)
     592              : ! *********************************************************************
     593              : 
     594      4337936 :  gam_now = zero
     595              : 
     596        48368 :  call zgemm('c','n',nbranch,nbranch,nbranch,cone,displ_red,nbranch,gam_bare,nbranch,czero,zgemm_tmp_mat,nbranch)
     597        48368 :  call zgemm('n','n',nbranch,nbranch,nbranch,cone,zgemm_tmp_mat,nbranch,displ_red,nbranch,czero,gam_now,nbranch)
     598              : 
     599        48368 : end subroutine gam_mult_displ
     600              : !!***
     601              : 
     602              : !!****f* ABINIT/complete_gamma
     603              : !!
     604              : !! NAME
     605              : !! complete_gamma
     606              : !!
     607              : !! FUNCTION
     608              : !! Use the set of special q points calculated by the Monkhorst & Pack Technique.
     609              : !! Check if all the information for the q points are present in the input gamma matrices.
     610              : !! Generate the gamma matrices (already summed over the FS) of the set of q points which
     611              : !! samples homogeneously the entire Brillouin zone.
     612              : !!
     613              : !! INPUTS
     614              : !! qpttoqpt = qpoint index mapping under symops
     615              : !!
     616              : !! OUTPUT
     617              : !! gamma_qpt = in/out: set of gamma matrix elements completed and symmetrized
     618              : !!    gamma_qpt(2,nbranch**2,nsppol,nqpt_full)
     619              : !!
     620              : !! SOURCE
     621              : 
     622           19 : subroutine complete_gamma(Cryst,nbranch,nsppol,nqptirred,nqpt_full,ep_scalprod,qirredtofull,qpttoqpt,gamma_qpt)
     623              : 
     624              : !Arguments ------------------------------------
     625              : !scalars
     626              :  integer,intent(in) :: nsppol,nbranch,nqptirred,nqpt_full,ep_scalprod
     627              :  type(crystal_t),intent(in) :: Cryst
     628              : !arrays
     629              :  integer,intent(in) :: qirredtofull(nqptirred)
     630              :  integer,intent(in) :: qpttoqpt(2,Cryst%nsym,nqpt_full)
     631              :  real(dp), intent(inout) :: gamma_qpt(2,nbranch**2,nsppol,nqpt_full)
     632              : 
     633              : !Local variables-------------------------------
     634              : !scalars
     635              :  integer :: ibranch,ieqqpt,natom,nsym,iqpt,isppol,isym
     636              :  integer :: itim,jbranch,neqqpt,iatom,ancestor_iatom,iqpt_fullbz
     637              : !arrays
     638           38 :  integer :: symmetrized_qpt(nqpt_full)
     639           38 :  integer :: gkk_flag(nbranch,nbranch,nsppol,nqpt_full)
     640              :  real(dp) :: ss(3,3)
     641           38 :  real(dp) :: tmp_mat(2,nbranch,nbranch)
     642           38 :  real(dp) :: tmp_mat2(2,nbranch,nbranch)
     643           38 :  real(dp) :: ss_allatoms(2,nbranch,nbranch)
     644              :  complex(dp) :: c_one, c_zero
     645           19 :  real(dp),allocatable :: gkk_qpt_new(:,:,:),gkk_qpt_tmp(:,:,:)
     646              : ! *********************************************************************
     647              : 
     648           19 :  c_one = dcmplx(one,zero)
     649           19 :  c_zero = dcmplx(zero,zero)
     650              : 
     651           19 :  natom = Cryst%natom
     652           19 :  nsym  = Cryst%nsym
     653              : 
     654              : !Generation of the gkk matrices relative to the q points
     655              : !of the set which samples the entire Brillouin zone
     656              : 
     657              : !set up flags for gamma_qpt matrices we have
     658        13163 :  gkk_flag = -1
     659          125 :  do iqpt=1,nqptirred
     660          106 :    iqpt_fullbz = qirredtofull(iqpt)
     661         1902 :    gkk_flag(:,:,:,iqpt_fullbz) = 1
     662              :  end do
     663              : 
     664          899 :  symmetrized_qpt(:) = -1
     665              : 
     666           76 :  ABI_MALLOC(gkk_qpt_new,(2,nbranch**2,nsppol))
     667           57 :  ABI_MALLOC(gkk_qpt_tmp,(2,nbranch**2,nsppol))
     668              : 
     669          899 :  do iqpt=1,nqpt_full
     670              : !
     671              : !  Already symmetrized?
     672          880 :    if (symmetrized_qpt(iqpt) == 1) cycle
     673              : 
     674         4130 :    gkk_qpt_new(:,:,:) = zero
     675              : 
     676              : !  loop over qpoints equivalent to iqpt
     677              :    neqqpt=0
     678              : !  do not use time reversal symmetry to complete the qpoints:
     679              : !  do not know what happens to the gamma matrices
     680              : !  11/2011: MJV: time reversal is needed here if inversion is absent
     681              : !  - used in read_gkk and all reductions of q-points by symmetry.
     682              : 
     683          318 :    do itim=1,2
     684         9822 :      do isym=1,nsym
     685              : !      ieqqpt is sent onto iqpt by itim/isym
     686         9504 :        ieqqpt = qpttoqpt(itim,isym,iqpt)
     687              : 
     688              : 
     689         9504 :        if (gkk_flag(1,1,1,ieqqpt) == -1) cycle
     690              : !      if we have information on this qpt
     691              : !      iqpt is equivalent to ieqqpt: get it from file or memory
     692       121932 :        gkk_qpt_tmp(:,:,:) = gamma_qpt(:,:,:,ieqqpt)
     693              : 
     694         3164 :        neqqpt=neqqpt+1
     695              : 
     696              : !
     697              : !      MJV note 02/2010:
     698              : !      the correspondence of symrel and symrec in the different cases, symmetrizing there
     699              : !      and back, has been fixed in the cases with and without scalprod (ie cartesian
     700              : !      and reduced real space coordinates) with respect to a calculation with no symmetries
     701              : !      I believe everything is settled, but still do not know why the 2 versions of the ss
     702              : !      matrices here use different rel/rec, instead of just being multiplied by the rprim gprim...
     703              : !
     704         3164 :        if (ep_scalprod==1) then
     705              :          ! ss(ii,jj)=ss(ii,jj)+Cryst%rprimd(ii,kk)*Cryst%symrel(kk,ll,isym)*Cryst%gprimd(ll,jj)
     706        63248 :          ss(:,:) = MATMUL(Cryst%rprimd, MATMUL(Cryst%symrel(:,:,isym), Cryst%gprimd))
     707              :        else
     708              :          ! ss(ii,jj) = Cryst%symrec(ii,jj,isym)
     709        34996 :          ss(:,:) = Cryst%symrec(:,:,isym)
     710              :        end if
     711              : 
     712       124964 :        ss_allatoms(:,:,:) = zero
     713         6648 :        do iatom=1,natom
     714         3484 :          ancestor_iatom = Cryst%indsym(4,isym,iatom)
     715        48456 :          ss_allatoms(1, (ancestor_iatom-1)*3+1:(ancestor_iatom-1)*3+3, (iatom-1)*3+1:(iatom-1)*3+3) = ss(1:3,1:3)
     716              :        end do
     717              : 
     718              : 
     719              : !      NOTE   ssinv(ii,jj)=ssinv(ii,jj)+Cryst%gprimd(ii,kk)*rprimd(jj,ll)*Cryst%symrec(ll,kk,isym)
     720              : 
     721         6692 :        do isppol=1,nsppol
     722              : !        multiply by the ss matrices
     723       129676 :          tmp_mat2(:,:,:) = zero
     724        13264 :          tmp_mat(:,:,:) = reshape(gkk_qpt_tmp(:,:,isppol),(/2,nbranch,nbranch/))
     725              : 
     726              :          call ZGEMM ('N','N',nbranch,nbranch,nbranch,&
     727         3316 : &         c_one,ss_allatoms,nbranch,tmp_mat,nbranch,c_zero,tmp_mat2,nbranch)
     728              : 
     729              :          call ZGEMM ('N','T',nbranch,nbranch,nbranch,&
     730         3316 : &         c_one,tmp_mat2,nbranch,ss_allatoms,nbranch,c_zero,tmp_mat,nbranch)
     731              : 
     732              : !        add to gkk_qpt_new
     733        23728 :          do ibranch =1,nbranch
     734        52708 :            do jbranch =1,nbranch
     735              :              gkk_qpt_new(:,(jbranch-1)*nbranch+ibranch,isppol) = &
     736       126360 : &             gkk_qpt_new(:,(jbranch-1)*nbranch+ibranch,isppol) + tmp_mat(:,jbranch,ibranch)
     737              :            end do
     738              :          end do
     739              :        end do ! isppol
     740              : !
     741              :      end do ! isym
     742              :    end do ! itim
     743              : !
     744          106 :    ABI_CHECK(neqqpt>0,'no q-points found equivalent to iqpt ')
     745              : !  Divide by number of equivalent qpts found.
     746         4130 :    gkk_qpt_new(:,:,:) = gkk_qpt_new(:,:,:)/neqqpt
     747              : 
     748              : !  copy the symmetrized version into all the equivalent qpoints, appropriately transformed
     749          337 :    do itim=1,2
     750        10596 :      do isym=1,nsym
     751              : !      ieqqpt is sent onto iqpt by itim/isym
     752         9504 :        ieqqpt = qpttoqpt(itim,isym,iqpt)
     753              : 
     754         9504 :        if (symmetrized_qpt(ieqqpt) /= -1) cycle
     755        27688 :        gkk_qpt_tmp(:,:,:) = zero
     756              : 
     757              : !      use symrec matrices to get inverse transform from isym^{-1}
     758          880 :        if (ep_scalprod==1) then
     759              :          ! Use inverse of symop matrix here to get back to ieqqpt (inv+transpose is in symrec and in gprimd)
     760              :          ! ss(ii,jj)=ss(ii,jj)+Cryst%rprimd(ii,kk)*Cryst%symrec(ll,kk,isym)*Cryst%gprimd(ll,jj)
     761         4288 :          ss(:,:) = MATMUL(Cryst%rprimd, MATMUL(TRANSPOSE(Cryst%symrec(:,:,isym)), Cryst%gprimd))
     762              :        else
     763              :           ! ss(ii,jj) = Cryst%symrel(jj,ii,isym)
     764        11024 :           ss(:,:) = TRANSPOSE(Cryst%symrel(:,:,isym))
     765              :        end if
     766              : 
     767        29296 :        ss_allatoms(:,:,:) = zero
     768         1784 :        do iatom=1,natom
     769          904 :          ancestor_iatom = Cryst%indsym(4,isym,iatom)
     770        12632 :          ss_allatoms(1, (ancestor_iatom-1)*3+1:(ancestor_iatom-1)*3+3, (iatom-1)*3+1:(iatom-1)*3+3) = ss(1:3,1:3)
     771              :        end do
     772              : 
     773              : !      ! Use inverse of symop matrix here to get back to ieqqpt
     774              : !      ssinv(ii,jj)=ssinv(ii,jj)+gprimd(ii,kk)*rprimd(jj,ll)*Cryst%symrel(kk,ll,isym)
     775              : 
     776         1768 :        do isppol=1,nsppol
     777              : !        multiply by the ss^{-1} matrices
     778        29544 :          tmp_mat2(:,:,:) = zero
     779         3552 :          tmp_mat(:,:,:) = reshape(gkk_qpt_new(:,:,isppol),(/2,nbranch,nbranch/))
     780              : 
     781              :          call ZGEMM ('N','N',nbranch,nbranch,nbranch,&
     782          888 : &         c_one,ss_allatoms,nbranch,tmp_mat,nbranch,c_zero,tmp_mat2,nbranch)
     783              : 
     784              :          call ZGEMM ('N','T',nbranch,nbranch,nbranch,&
     785          888 : &         c_one,tmp_mat2,nbranch,ss_allatoms,nbranch,c_zero,tmp_mat,nbranch)
     786              : 
     787              : !        FIXME: the following could just be a reshape
     788         3624 :          do ibranch =1,nbranch
     789        12264 :            do jbranch =1,nbranch
     790              :              gkk_qpt_tmp(:,(jbranch-1)*nbranch+ibranch,isppol) =&
     791        28656 : &             tmp_mat(:,jbranch,ibranch)
     792              :            end do
     793              :          end do
     794        11476 :          if (gkk_flag (1,1,isppol,ieqqpt) == -1) gkk_flag (:,:,isppol,ieqqpt) = 0
     795              :        end do ! end isppol do
     796              : 
     797              : !      save symmetrized matrices for qpt ieqqpt
     798        27688 :        gamma_qpt(:,:,:,ieqqpt) = gkk_qpt_tmp(:,:,:)
     799              : 
     800         9716 :        symmetrized_qpt(ieqqpt) = 1
     801              : 
     802              :      end do !isym
     803              :    end do !itim
     804              :  end do !iqpt
     805              : 
     806           19 :  ABI_FREE(gkk_qpt_new)
     807           19 :  ABI_FREE(gkk_qpt_tmp)
     808              : 
     809           19 : end subroutine complete_gamma
     810              : !!***
     811              : 
     812              : !!****f* ABINIT/complete_gamma_tr
     813              : !!
     814              : !! NAME
     815              : !! complete_gamma_tr
     816              : !!
     817              : !! FUNCTION
     818              : !! Use the set of special q points calculated by the Monkhorst & Pack Technique.
     819              : !! Check if all the information for the q points are present in
     820              : !! the input gamma transport matrices.
     821              : !! Generate the gamma transport matrices (already summed over the FS) of the set of q points which
     822              : !! samples homogeneously the entire Brillouin zone.
     823              : !!
     824              : !! INPUTS
     825              : !! crystal<crystal_t>=data type gathering info on the crystalline structure.
     826              : !! ep_scalprod= flag for scalar product of gkk with phonon displacement vectors
     827              : !! nbranch=number of phonon branches = 3*natom
     828              : !! nqptirred=nqpt irred BZ
     829              : !! nqpt_full=nqpt full BZ
     830              : !! nsppol=number of spins
     831              : !! qirredtofull= mapping irred to full qpoints
     832              : !! qpttoqpt = qpoint index mapping under symops
     833              : !!
     834              : !! OUTPUT
     835              : !! gamma_qpt_tr = in/out: set of gamma matrix elements completed and symmetrized
     836              : !!    gamma_qpt_tr(2,9,nbranch*nbranch,nsppol,nqpt_full)
     837              : !!
     838              : !! SOURCE
     839              : 
     840           10 : subroutine complete_gamma_tr(crystal,ep_scalprod,nbranch,nqptirred,nqpt_full,nsppol,gamma_qpt_tr,qirredtofull,qpttoqpt)
     841              : 
     842              :  use m_linalg_interfaces
     843              : 
     844              : !Arguments ------------------------------------
     845              : !scalars
     846              :  integer, intent(in) :: nbranch,nqptirred,nqpt_full,nsppol, ep_scalprod
     847              :  type(crystal_t),intent(in) :: crystal
     848              : !arrays
     849              :  integer,intent(in) :: qpttoqpt(2,crystal%nsym,nqpt_full)
     850              :  integer,intent(in) :: qirredtofull(nqptirred)
     851              :  real(dp), intent(inout) :: gamma_qpt_tr(2,9,nbranch*nbranch,nsppol,nqpt_full)
     852              : 
     853              : !Local variables-------------------------------
     854              : !scalars
     855              :  integer :: ieqqpt,iqpt,isppol,isym
     856              :  integer :: itim,neqqpt
     857              :  integer :: iatom,ancestor_iatom
     858              :  integer :: iqpt_fullbz,imode, itensor,reim
     859              :  real(dp),parameter :: tol=2.d-8
     860              : !arrays
     861           20 :  integer :: symrel(3,3,crystal%nsym),symrec(3,3,crystal%nsym)
     862           20 :  integer :: symmetrized_qpt(nqpt_full)
     863           20 :  integer :: gkk_flag(nbranch,nbranch,nsppol,nqpt_full)
     864              :  real(dp) :: gprimd(3,3),rprimd(3,3)
     865              :  real(dp) :: ss(3,3), sscart(3,3)
     866           20 :  real(dp) :: tmp_mat(nbranch,nbranch)
     867           20 :  real(dp) :: tmp_mat2(nbranch,nbranch)
     868              :  real(dp) :: tmp_tensor(3,3)
     869              :  real(dp) :: tmp_tensor2(3,3)
     870           20 :  real(dp) :: ss_allatoms(nbranch,nbranch)
     871           10 :  real(dp),allocatable :: gkk_qpt_new(:,:,:,:),gkk_qpt_tmp(:,:,:,:)
     872              : ! *********************************************************************
     873              : 
     874          130 :  gprimd = crystal%gprimd
     875          130 :  rprimd = crystal%rprimd
     876              : 
     877         4066 :  symrec =  crystal%symrec
     878         4066 :  symrel =  crystal%symrel
     879              : 
     880              : !Generation of the gkk matrices relative to the q points
     881              : !of the set which samples the entire Brillouin zone
     882              : 
     883              : !set up flags for gamma_qpt matrices we have
     884         2570 :  gkk_flag = -1
     885           46 :  do iqpt=1,nqptirred
     886           36 :    iqpt_fullbz = qirredtofull(iqpt)
     887         1234 :    gkk_flag(:,:,:,iqpt_fullbz) = 1
     888              :  end do
     889              : 
     890           90 :  symmetrized_qpt(:) = -1
     891              : ! isppol=1
     892              : 
     893           40 :  ABI_MALLOC(gkk_qpt_new,(2,9,nbranch*nbranch, nsppol))
     894           30 :  ABI_MALLOC(gkk_qpt_tmp,(2,9,nbranch*nbranch, nsppol))
     895              : 
     896           90 :  do iqpt=1,nqpt_full
     897              : 
     898              : !  Already symmetrized?
     899           80 :    if (symmetrized_qpt(iqpt) == 1) cycle
     900              : 
     901        27288 :    gkk_qpt_new(:,:,:,:) = zero
     902              : 
     903              : !  loop over qpoints equivalent to iqpt
     904              :    neqqpt=0
     905              : !  do not use time reversal symmetry to complete the qpoints:
     906              : !  do not know what happens to the gamma matrices
     907              : 
     908          108 :    do itim=1,2
     909         2220 :      do isym=1,crystal%nsym
     910              : !      ieqqpt is sent onto iqpt by itim/isym
     911         2112 :        ieqqpt = qpttoqpt(itim,isym,iqpt)
     912              : 
     913         2112 :        if (gkk_flag(1,1,1,ieqqpt) == -1) cycle
     914              : !      if we have information on this qpt
     915              : !      iqpt is equivalent to ieqqpt: get it from file or memory
     916       800832 :        gkk_qpt_tmp(:,:,:,:) = gamma_qpt_tr(:,:,:,:,ieqqpt)
     917              : 
     918         1248 :        neqqpt=neqqpt+1
     919              : 
     920              : !
     921              : !      MJV note 02/2010:
     922              : !      the correspondence of symrel and symrec in the different cases, symmetrizing there
     923              : !      and back, has been fixed in the cases with and without scalprod (ie cartesian
     924              : !      and reduced real space coordinates) with respect to a calculation with no symmetries
     925              : !      I believe everything is settled, but still do not know why the 2 versions of the ss
     926              : !      matrices here use different rel/rec, instead of just being multiplied by the rprim gprim...
     927              : !
     928              :        ! sscart(ii,jj)=sscart(ii,jj)+rprimd(ii,kk)*symrel(kk,ll,isym)*gprimd(ll,jj)
     929       113568 :        sscart(:,:) = MATMUL(rprimd, MATMUL(symrel(:,:,isym), gprimd))
     930         1248 :        if (ep_scalprod==1) then
     931              :          ! ss(ii,jj)=ss(ii,jj)+rprimd(ii,kk)*symrel(kk,ll,isym)*gprimd(ll,jj)
     932        85904 :          ss(:,:) = MATMUL(rprimd, MATMUL(symrel(:,:,isym), gprimd))
     933              :        else
     934              :          ! ss(ii,jj) = symrec(ii,jj,isym)
     935         3952 :          ss(:,:) = symrec(:,:,isym)
     936              :        end if
     937              : 
     938        35424 :        ss_allatoms(:,:) = zero
     939         3136 :        do iatom=1,crystal%natom
     940         1888 :          ancestor_iatom = crystal%indsym(4,isym,iatom)
     941              :          ss_allatoms((ancestor_iatom-1)*3+1:(ancestor_iatom-1)*3+3,&
     942        25792 : &         (iatom-1)*3+1:         (iatom-1)*3+3) = ss(1:3,1:3)
     943              :        end do
     944              : 
     945              : 
     946              : !      NOTE   ssinv(ii,jj)=ssinv(ii,jj)+gprimd(ii,kk)*rprimd(jj,ll)*symrec(ll,kk,isym)
     947              : 
     948         2568 :        do isppol=1,nsppol
     949              : 
     950              : !        for each tensor component, rotate the cartesian directions of phonon modes
     951        12480 :          do itensor = 1, 9
     952        34944 :            do reim=1,2  ! Real/Imaginary parts
     953              : !            Multiply by the ss matrices
     954       637632 :              tmp_mat2(:,:) = zero
     955        67392 :              tmp_mat(:,:) = reshape(gkk_qpt_tmp(reim,itensor,:,isppol),(/nbranch,nbranch/))
     956        22464 :              call DGEMM ('N','N',nbranch,nbranch,nbranch,one,ss_allatoms,nbranch,tmp_mat,nbranch,zero,tmp_mat2,nbranch)
     957        22464 :              call DGEMM ('N','T',nbranch,nbranch,nbranch,one,tmp_mat2,nbranch,ss_allatoms,nbranch,zero,tmp_mat,nbranch)
     958       569376 :              gkk_qpt_tmp(reim,itensor,:,isppol) = reshape (tmp_mat, (/nbranch*nbranch/))
     959              :            enddo
     960              :          end do ! itensor
     961              : 
     962              : !        for each cartesian direction/phonon mode, rotate the tensor components
     963        29760 :          do imode = 1, nbranch*nbranch
     964        86784 :            do reim=1,2  ! Real/Imaginary parts
     965        57024 :              tmp_tensor2(:,:) = zero
     966        57024 :              tmp_tensor(:,:) = reshape(gkk_qpt_tmp(reim,:,imode,isppol),(/3,3/))
     967        57024 :              call DGEMM ('N','N',3,3,3,one,sscart,3,tmp_tensor,3,zero,tmp_tensor2,3)
     968        57024 :              call DGEMM ('N','T',3,3,3,one,tmp_tensor2,3,sscart,3,zero,tmp_tensor,3)
     969       598752 :              gkk_qpt_tmp(reim,:,imode,isppol) = reshape (tmp_tensor, (/9/)) ! modified by BX
     970              :            enddo
     971              :          end do ! imode
     972              : 
     973              : !        add to gkk_qpt_new
     974       800832 :          gkk_qpt_new(:,:,:,isppol) = gkk_qpt_new(:,:,:,isppol) + gkk_qpt_tmp(:,:,:,isppol)
     975              : 
     976              :        end do ! end isppol do
     977              : 
     978              :      end do ! end isym do
     979              :    end do ! end itim do
     980              : 
     981           36 :    ABI_CHECK(neqqpt>0,'no q-points found equivalent to iqpt ')
     982              : 
     983              : !  divide by number of equivalent qpts found
     984        27288 :    gkk_qpt_new = gkk_qpt_new/neqqpt
     985              : 
     986              : 
     987              : !  copy the symmetrized version into all the equivalent qpoints, appropriately transformed
     988          118 :    do itim=1,2
     989         2264 :      do isym=1,crystal%nsym
     990              : !      ieqqpt is sent onto iqpt by itim/isym
     991         2112 :        ieqqpt = qpttoqpt(itim,isym,iqpt)
     992              : 
     993         2112 :        if (symmetrized_qpt(ieqqpt) /= -1) cycle
     994        56608 :        gkk_qpt_tmp = zero
     995              : 
     996              : !      use symrec matrices to get inverse transform from isym^{-1}
     997              : !              Use inverse of symop matrix here to get back to ieqqpt (inv+transpose is in symrec and in gprimd)
     998              : !              sscart(ii,jj)=sscart(ii,jj)+rprimd(ii,kk)*symrec(ll,kk,isym)*gprimd(ll,jj)
     999              :        ! sscart(ii,jj)=sscart(ii,jj)+rprimd(ii,kk)*symrec(ll,kk,isym)*gprimd(ll,jj)
    1000         7280 :        sscart(:,:) = MATMUL(rprimd, MATMUL(TRANSPOSE(symrec(:,:,isym)), gprimd))
    1001           80 :        if (ep_scalprod==1) then
    1002              : !                Use inverse of symop matrix here to get back to ieqqpt (inv+transpose is in symrec and in gprimd)
    1003              :          ! ss(ii,jj)=ss(ii,jj)+rprimd(ii,kk)*symrec(ll,kk,isym)*gprimd(ll,jj)
    1004         5824 :          ss(:,:) = MATMUL(rprimd, MATMUL(TRANSPOSE(symrec(:,:,isym)), gprimd))
    1005              : 
    1006              :        else
    1007              :          ! ss(ii,jj) = symrel(jj,ii,isym)
    1008          208 :          ss(:,:) = TRANSPOSE(symrel(:,:,isym))
    1009              :        end if
    1010              : 
    1011         2480 :        ss_allatoms(:,:) = zero
    1012          208 :        do iatom=1,crystal%natom
    1013          128 :          ancestor_iatom = crystal%indsym(4,isym,iatom)
    1014              :          ss_allatoms((ancestor_iatom-1)*3+1:(ancestor_iatom-1)*3+3,&
    1015         1744 : &         (iatom-1)*3+1:          (iatom-1)*3+3) = ss(1:3,1:3)
    1016              :        end do
    1017              : 
    1018              : !      ! Use inverse of symop matrix here to get back to ieqqpt
    1019              : !      ssinv(ii,jj)=ssinv(ii,jj)+gprimd(ii,kk)*rprimd(jj,ll)*symrel(kk,ll,isym)
    1020              : 
    1021          160 :        do isppol=1,nsppol
    1022          800 :          do itensor = 1, 9
    1023         2240 :            do reim=1,2  ! Real/Imaginary parts
    1024              : !            Multiply by the ss^{-1} matrices
    1025        44640 :              tmp_mat2(:,:) = zero
    1026         4320 :              tmp_mat(:,:) = reshape(gkk_qpt_new(reim,itensor,:,isppol),(/nbranch,nbranch/))
    1027         1440 :              call DGEMM ('N','N',nbranch,nbranch,nbranch,one,ss_allatoms,nbranch,tmp_mat,nbranch,zero,tmp_mat2,nbranch)
    1028         1440 :              call DGEMM ('N','T',nbranch,nbranch,nbranch,one,tmp_mat2,nbranch,ss_allatoms,nbranch,zero,tmp_mat,nbranch)
    1029        39888 :              gkk_qpt_tmp(reim,itensor,:,isppol) = reshape (tmp_mat, (/nbranch*nbranch/))
    1030              :            enddo
    1031              :          end do ! itensor
    1032              : 
    1033              : !        for each cartesian direction/phonon mode, rotate the tensor components
    1034         2096 :          do imode = 1, nbranch*nbranch
    1035         6128 :            do reim=1,2  ! Real/Imaginary parts
    1036         4032 :              tmp_tensor2(:,:) = zero
    1037         4032 :              tmp_tensor(:,:) = reshape(gkk_qpt_tmp(reim,:,imode,isppol),(/3,3/))
    1038         4032 :              call DGEMM ('N','N',3,3,3,one,sscart,3,tmp_tensor,3,zero,tmp_tensor2,3)
    1039         4032 :              call DGEMM ('N','T',3,3,3,one,tmp_tensor2,3,sscart,3,zero,tmp_tensor,3)
    1040              : !            gkk_qpt_new(:,:,imode,isppol) = reshape (tmp_tensor, (/2,9/)) ! Modified by BX
    1041        42336 :              gkk_qpt_tmp(reim,:,imode,isppol) = reshape (tmp_tensor, (/9/)) ! Modified by BX
    1042              :            enddo
    1043              :          end do ! imode
    1044              : 
    1045          160 :          if (gkk_flag (1,1,isppol,ieqqpt) == -1) then
    1046         1292 :            gkk_flag (:,:,isppol,ieqqpt) = 0
    1047              :          end if
    1048              : 
    1049              :        end do ! end isppol do
    1050              : 
    1051              : 
    1052              : !      save symmetrized matrices for qpt ieqqpt
    1053        56608 :        gamma_qpt_tr(:,:,:,:,ieqqpt) = gkk_qpt_tmp(:,:,:,:)
    1054              : 
    1055          152 :        symmetrized_qpt(ieqqpt) = 1
    1056              : 
    1057              :      end do ! end isym do
    1058              :    end do ! end itim do
    1059              : 
    1060              :  end do
    1061              : !end iqpt do
    1062              : 
    1063           10 :  ABI_FREE(gkk_qpt_new)
    1064           10 :  ABI_FREE(gkk_qpt_tmp)
    1065              : 
    1066           10 : end subroutine complete_gamma_tr
    1067              : !!***
    1068              : 
    1069              : !----------------------------------------------------------------------
    1070              : 
    1071              : !!****f* m_fstab/mkqptequiv
    1072              : !! NAME
    1073              : !! mkqptequiv
    1074              : !!
    1075              : !! FUNCTION
    1076              : !! This routine determines the equivalence between
    1077              : !!   1) qpoints and fermi surface kpoints
    1078              : !!   2) qpoints under symmetry operations
    1079              : !!
    1080              : !! INPUTS
    1081              : !!   Cryst<crystal_t>=Info on unit cell and symmetries.
    1082              : !!   kpt_phon = fermi surface kpoints
    1083              : !!   nkpt_phon = number of kpoints in the full FS set
    1084              : !!   nqpt = number of qpoints
    1085              : !!   qpt_full = qpoint coordinates
    1086              : !!
    1087              : !! OUTPUT
    1088              : !!   FSfullpqtofull = mapping of k + q onto k' for k and k' in full BZ
    1089              : !!   qpttoqpt(itim,isym,iqpt) = qpoint index which transforms to iqpt under isym and with time reversal itim.
    1090              : !!
    1091              : !! NOTES
    1092              : !!   REMOVED 3/6/2008: much too large matrix, and not used at present
    1093              : !!       FStoqpt = mapping of kpoint pairs (1 irreducible and 1 full) to qpoints
    1094              : !!
    1095              : !! SOURCE
    1096              : 
    1097           15 : subroutine mkqptequiv(FSfullpqtofull,Cryst,kpt_phon,nkpt_phon,nqpt,qpttoqpt,qpt_full,mqtofull)
    1098              : 
    1099              : !Arguments ------------------------------------
    1100              : !scalars
    1101              :  integer,intent(in) :: nkpt_phon,nqpt
    1102              :  type(crystal_t),intent(in) :: Cryst
    1103              : !arrays
    1104              :  integer,intent(out) :: FSfullpqtofull(nkpt_phon,nqpt),qpttoqpt(2,Cryst%nsym,nqpt)
    1105              :  integer,intent(out),optional :: mqtofull(nqpt)
    1106              :  real(dp),intent(in) :: kpt_phon(3,nkpt_phon),qpt_full(3,nqpt)
    1107              : 
    1108              : !Local variables-------------------------------
    1109              : !scalars
    1110              :  integer :: ikpt_phon,iFSqpt,iqpt,isym,symrankkpt_phon
    1111              :  !character(len=500) :: message
    1112           15 :  type(krank_t) :: krank
    1113              : !arrays
    1114              :  real(dp) :: tmpkpt(3),gamma_kpt(3)
    1115              : ! *************************************************************************
    1116              : 
    1117           15 :  call wrtout(std_out,' mkqptequiv : making rankkpt_phon and invrankkpt_phon',"COLL")
    1118              : 
    1119           15 :  call krank%init(nkpt_phon, kpt_phon)
    1120              : 
    1121        10631 :  FSfullpqtofull = -999
    1122              :  gamma_kpt(:) = zero
    1123              : 
    1124         1327 :  do ikpt_phon=1,nkpt_phon
    1125        11823 :    do iqpt=1,nqpt
    1126              :      ! tmpkpt = jkpt = ikpt + qpt
    1127        41984 :      tmpkpt(:) = kpt_phon(:,ikpt_phon) + qpt_full(:,iqpt)
    1128              : 
    1129              :      ! which kpt is it among the full FS kpts?
    1130        10496 :      symrankkpt_phon = krank%get_rank(tmpkpt)
    1131              : 
    1132        10496 :      FSfullpqtofull(ikpt_phon,iqpt) = krank%invrank(symrankkpt_phon)
    1133        11808 :      if (FSfullpqtofull(ikpt_phon, iqpt) == -1) then
    1134            0 :        ABI_ERROR("looks like no kpoint equiv to k+q !!!")
    1135              :      end if
    1136              : 
    1137              :    end do
    1138              :  end do
    1139              : 
    1140           15 :  if (present(mqtofull)) then
    1141            0 :    do iqpt=1,nqpt
    1142            0 :      tmpkpt(:) = gamma_kpt(:) - qpt_full(:,iqpt)
    1143              : 
    1144              :      ! which kpt is it among the full FS kpts?
    1145            0 :      symrankkpt_phon = krank%get_rank(tmpkpt)
    1146              : 
    1147            0 :      mqtofull(iqpt) = krank%invrank(symrankkpt_phon)
    1148            0 :      if (mqtofull(iqpt) == -1) then
    1149            0 :        ABI_ERROR("looks like no kpoint equiv to -q !!!")
    1150              :      end if
    1151              :    end do
    1152              :  end if
    1153              : 
    1154           15 :  call krank%free()
    1155              : 
    1156              :  ! start over with q grid
    1157           15 :  call wrtout(std_out,' mkqptequiv : FSfullpqtofull made. Do qpttoqpt',"COLL")
    1158              : 
    1159           15 :  call krank%init(nqpt, qpt_full)
    1160              : 
    1161        15399 :  qpttoqpt(:,:,:) = -1
    1162          135 :  do iFSqpt=1,nqpt
    1163         5223 :    do isym=1,Cryst%nsym
    1164              :      tmpkpt(:) =  Cryst%symrec(:,1,isym)*qpt_full(1,iFSqpt) &
    1165              :                 + Cryst%symrec(:,2,isym)*qpt_full(2,iFSqpt) &
    1166        20352 :                 + Cryst%symrec(:,3,isym)*qpt_full(3,iFSqpt)
    1167              : 
    1168         5088 :      symrankkpt_phon = krank%get_rank(tmpkpt)
    1169         5088 :      if (krank%invrank(symrankkpt_phon) == -1) then
    1170            0 :        ABI_ERROR("looks like no kpoint equiv to q by symmetry without time reversal!!!")
    1171              :      end if
    1172         5088 :      qpttoqpt(1,isym,krank%invrank(symrankkpt_phon)) = iFSqpt
    1173              : 
    1174        20352 :      tmpkpt = -tmpkpt
    1175         5088 :      symrankkpt_phon = krank%get_rank(tmpkpt)
    1176         5088 :      if (krank%invrank(symrankkpt_phon) == -1) then
    1177            0 :        ABI_ERROR('looks like no kpoint equiv to q by symmetry with time reversal!!!')
    1178              :      end if
    1179         5208 :      qpttoqpt(2,isym,krank%invrank(symrankkpt_phon)) = iFSqpt
    1180              :    end do
    1181              :  end do
    1182              : 
    1183           15 :  call krank%free()
    1184              : 
    1185           15 : end subroutine mkqptequiv
    1186              : !!***
    1187              : 
    1188          504 : end module defs_elphon
    1189              : !!***
        

Generated by: LCOV version 2.3-1