LCOV - code coverage report
Current view: top level - src/71_wannier - m_wannier_builder.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 75.6 % 283 214
Test Date: 2026-11-07 19:31:18 Functions: 66.7 % 33 22
Branches: 51.3 % 727 373

             Branch data     Line data    Source code
       1                 :             : !!****m*ABINIT/m_wannier_builder
       2                 :             : !! NAME
       3                 :             : !!  m_wannier_builder
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!  Algorithms for building Wannier functions
       7                 :             : !!  Methods:
       8                 :             : !!  SCDM (select columns of density matrix method) and
       9                 :             : !!  projected wannier function (PWF)
      10                 :             : !! COPYRIGHT
      11                 :             : !!  Copyright (C) 2005-2026 ABINIT group (hexu)
      12                 :             : !!  This file is distributed under the terms of the
      13                 :             : !!  GNU General Public License, see ~abinit/COPYING
      14                 :             : !!  or http://www.gnu.org/copyleft/gpl.txt .
      15                 :             : !!
      16                 :             : !! SOURCE
      17                 :             : !!
      18                 :             : !! Todolist:
      19                 :             : !! - output of Wannier90 format Amn, Mmn, eigenvalue files
      20                 :             : !! - output header in netcdf file
      21                 :             : !! - allow units in Hamiltonian
      22                 :             : !! - projected wannier functions
      23                 :             : 
      24                 :             : #if defined HAVE_CONFIG_H
      25                 :             : #include "config.h"
      26                 :             : #endif
      27                 :             : 
      28                 :             : 
      29                 :             : #include "abi_common.h"
      30                 :             : 
      31                 :             : 
      32                 :             : !===============================================================
      33                 :             : ! SCDM-k
      34                 :             : !> @description: Select Column Density matrix method for
      35                 :             : !   generating Wannier functions.
      36                 :             : !===============================================================
      37                 :             : module m_wannier_builder
      38                 :             :   use defs_basis
      39                 :             :   use m_abicore
      40                 :             :   use m_errors
      41                 :             :   use m_io_tools,        only : open_file
      42                 :             :   use m_fstrings,        only : ltoa
      43                 :             :   use m_scdm_math, only: complex_QRCP_piv_only, complex_svd, tpi_im, &
      44                 :             :        & gaussian, fermi, insertion_sort_double, eigensolver
      45                 :             :   use m_wann_netcdf, only: IOWannNC
      46                 :             :   implicit none
      47                 :             :   public:: WannierBuilder_t
      48                 :             :   public :: WannierBuilder_witheigen_t
      49                 :             :   public:: Amn_to_H
      50                 :             :   private
      51                 :             : 
      52                 :             : 
      53                 :             :   !===============================================================
      54                 :             :   ! WannierBuilder_t type:
      55                 :             :   !> @ description: the class for scdmk method.
      56                 :             :   !===============================================================
      57                 :             :   type::  WannierBuilder_t
      58                 :             : 
      59                 :             :      ! Inputs
      60                 :             :      real(dp), allocatable:: kpts(:, :) !(idim, ikpt)
      61                 :             :      real(dp), allocatable:: kweights(:) !(ikpt)
      62                 :             :      !real(dp), allocatable:: weight(:, :) !(iband, ikpt)
      63                 :             :      integer, allocatable:: exclude_bands(:)
      64                 :             : 
      65                 :             :      integer:: method = 0  ! 1: SCDM-k 2: projected wf
      66                 :             :      ! Disentanglement
      67                 :             :      integer:: disentangle_func_type  ! 1:unity  2: erfc function 3: gauss function
      68                 :             :      real(dp):: mu, sigma
      69                 :             : 
      70                 :             :      ! Projected Wannier function related
      71                 :             :      complex(dp), allocatable:: projectors(:, :)
      72                 :             : 
      73                 :             :      ! SCDM related
      74                 :             :      integer, allocatable:: cols(:)
      75                 :             :      real(dp), allocatable:: anchor_kpt(:)
      76                 :             :      integer:: anchor_ikpt
      77                 :             :      integer, allocatable:: anchor_ibands(:)
      78                 :             :      logical:: project_to_anchor = .False.
      79                 :             : 
      80                 :             :      ! Output Wannier function and Hamiltonian
      81                 :             :      integer:: nwann, nkpt, nband, nbasis, nkdim
      82                 :             :      integer:: dim  ! dimension of position
      83                 :             :      integer:: nR
      84                 :             :      integer, allocatable:: Rlist(:,:) !(idim, iRpt)
      85                 :             :      complex(dp), allocatable:: Amnk(:, :, :) !(nband, nwann, nkpt)
      86                 :             :      complex(dp), allocatable:: Hwannk(:, :, :) !(nwann, nwann, nkpt)
      87                 :             : 
      88                 :             :      complex(dp), allocatable:: psi_wann_k(:, :, :)  !(nbasis, nwann, nkpt)
      89                 :             : 
      90                 :             :      complex(dp), allocatable:: HwannR(:, :, :) !(nwann, nwann, nR)
      91                 :             :      complex(dp), allocatable:: wannR(:,:,:) !(nbasis, nwann, nR)
      92                 :             : 
      93                 :             :    contains
      94                 :             :      procedure:: initialize
      95                 :             :      procedure:: finalize
      96                 :             :      procedure:: get_psi_k
      97                 :             :      procedure:: get_evals_k
      98                 :             :      procedure:: run_all
      99                 :             :      procedure:: find_kpoint
     100                 :             :      !procedure:: remove_phase
     101                 :             :      procedure:: auto_find_anchors
     102                 :             :      procedure:: get_columns
     103                 :             :      procedure:: get_scdm_Amnk  ! Amnk for all kpoints
     104                 :             :      procedure:: get_projected_Amnk  ! Amnk for all kpoints
     105                 :             :      procedure:: get_Amnk
     106                 :             :      procedure:: get_weight
     107                 :             :      procedure:: set_anchor
     108                 :             :      procedure:: set_disp_projector
     109                 :             :      procedure:: set_mode_projector
     110                 :             :      procedure:: get_wannR_and_HwannR
     111                 :             :      procedure:: select_columns
     112                 :             :      procedure:: construct_wannier
     113                 :             :      procedure:: write_Amnk_w90
     114                 :             :      procedure:: write_Hwann_w90
     115                 :             :      procedure:: create_ncfile
     116                 :             :      procedure:: close_ncfile
     117                 :             :      procedure:: write_wann_netcdf
     118                 :             :      procedure:: get_wannier_eigen
     119                 :             :      procedure:: get_wannier_eigen_klist
     120                 :             :   end type WannierBuilder_t
     121                 :             : 
     122                 :             : 
     123                 :             :   ! Extends WannierBuilder_t with pointer to eigens.
     124                 :             :   type, extends(WannierBuilder_t):: WannierBuilder_witheigen_t
     125                 :             :      real(dp),  pointer:: evals(:, :) => null()   !(iband, ikpt)
     126                 :             :      complex(dp),  pointer:: psi(:, :, :) => null() ! (ibasis, iband, ikpt)
     127                 :             :    contains
     128                 :             :      procedure :: set_eigen => set_eigen
     129                 :             :      procedure :: get_psi_k => get_psi_k_from_eigen
     130                 :             :      procedure :: get_evals_k => get_evals_k_from_eigen
     131                 :             :   end type WannierBuilder_witheigen_t
     132                 :             : 
     133                 :             : contains
     134                 :             : 
     135                 :             :   !===============================================================
     136                 :             :   !
     137                 :             :   !> @
     138                 :             :   !> kpts: kpoints. indices: (idim, ikpt)
     139                 :             :   !> kweights: kweights. indices: (ikpt)
     140                 :             :   !> nwann: number of Wannier functions to be calcualted.
     141                 :             :   !> nbasis: number of basis in the original wavefunction.
     142                 :             :   !> disentangle_func_type: the type of the disentanglement function. 1: unity function. 2. Fermi. 3. Gauss
     143                 :             :   !> project_to_anchor: whether to multiply the weight function by the projection to the anchor states.
     144                 :             :   !===============================================================
     145   [ -  +  -  +  :           3 :   subroutine initialize(self,kpts, kweights, Rlist, nwann, nbasis, nband, &
                   -  + ]
     146   [ +  -  +  - ]:           3 :        &  disentangle_func_type, mu, sigma, exclude_bands, project_to_anchor, method)
     147                 :             :     class(WannierBuilder_t), intent(inout):: self
     148                 :             :     integer, intent(in):: nwann, nbasis, nband
     149                 :             :     real(dp), intent(in):: kpts(:, :)  !(idim, ikpt)
     150                 :             :     real(dp), intent(in):: kweights(:)  !(ikpt)
     151                 :             :     integer, intent(in):: Rlist(:, :)  !(idim, iRpt)
     152                 :             :     integer, optional, intent(in):: disentangle_func_type
     153                 :             :     real(dp), optional, intent(in):: mu, sigma
     154                 :             :     integer, optional, intent(in):: exclude_bands(:)
     155                 :             :     logical, optional, intent(in):: project_to_anchor
     156                 :             :     integer, intent(in):: method
     157                 :             : 
     158                 :           3 :     self%nkdim = size(kpts, 1)
     159                 :           3 :     self%nkpt = size(kpts, 2)
     160                 :           3 :     self%nwann = nwann
     161                 :           3 :     self%nbasis = nbasis
     162                 :           3 :     self%nband = nband
     163                 :           3 :     self%method = method
     164                 :             :     !if (present(psi_phase)) then
     165                 :             :     !    if (psi_phase) then
     166                 :             :     !        ABI_MALLOC(self%psi, (self%nbasis, self%nband, self%nkpt))
     167                 :             :     !        call self%remove_phase(psi)
     168                 :             :     !    else
     169                 :             :     !        self%psi => psi
     170                 :             :     !    end if
     171                 :             :     !else
     172                 :             :     !    self%psi => psi
     173                 :             :     !end if
     174                 :             : 
     175   [ -  +  +  -  :           9 :     ABI_MALLOC(self%cols, (self%nwann))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     176         [ +  + ]:          12 :     self%cols(:) = 0
     177   [ -  +  +  -  :          12 :     ABI_MALLOC(self%kpts, (self%nkdim, self%nkpt))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
     178   [ +  -  +  -  :         774 :     self%kpts = kpts
          -  +  -  -  +  
                +  +  + ]
     179   [ -  +  +  -  :           9 :     ABI_MALLOC(self%kweights, (self%nkpt))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     180   [ +  -  -  +  :         198 :     self%kweights = kweights
             -  -  +  + ]
     181                 :             : 
     182                 :           3 :     self%nR = size(Rlist, 2)
     183   [ -  +  +  -  :          12 :     ABI_MALLOC(self%Rlist, (self%nkdim, self%nR))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
     184   [ +  -  +  -  :         774 :     self%Rlist = Rlist
          -  +  -  -  +  
                +  +  + ]
     185                 :             : 
     186                 :             :     !ABI_MALLOC(self%weight, (self%nband, self%nkpt))
     187                 :             :     !self%weight(:, :) = 0.0_dp
     188                 :             : 
     189         [ +  - ]:           3 :     if (present(disentangle_func_type)) then
     190                 :           3 :        self%disentangle_func_type = disentangle_func_type
     191                 :             :     else
     192                 :           0 :        self%disentangle_func_type = 0
     193                 :             :     end if
     194                 :             : 
     195         [ +  - ]:           3 :     if (present(mu)) then
     196                 :           3 :        self%mu = mu
     197                 :             :     else
     198                 :           0 :        self%mu = 0
     199                 :             :     end if
     200                 :             : 
     201         [ +  - ]:           3 :     if (present(sigma)) then
     202                 :           3 :        self%sigma = sigma
     203                 :             :     else
     204                 :           0 :        self%sigma = sigma
     205                 :             :     end if
     206                 :             : 
     207   [ -  +  +  -  :          15 :     ABI_MALLOC(self%Amnk, (self%nband, self%nwann, self%nkpt))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
     208   [ -  +  +  -  :          15 :     ABI_MALLOC(self%psi_wann_k, (self%nbasis, self%nwann, self%nkpt))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
     209   [ -  +  +  -  :          15 :     ABI_MALLOC(self%Hwannk, (self%nwann, self%nwann, self%nkpt))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
     210                 :             : 
     211         [ +  - ]:           3 :     if (present(exclude_bands)) then
     212   [ +  -  -  -  :           9 :        ABI_MALLOC(self%exclude_bands, (size(exclude_bands, 1)))
          +  -  -  +  -  
             +  -  +  -  
                      + ]
     213                 :             :     end if
     214                 :             : 
     215         [ +  - ]:           3 :     if (present(project_to_anchor)) self%project_to_anchor = project_to_anchor
     216                 :           3 :   end subroutine initialize
     217                 :             : 
     218                 :             : 
     219                 :             : 
     220                 :           3 :   subroutine finalize(self)
     221                 :             :     class(WannierBuilder_t), intent(inout):: self
     222         [ +  - ]:           3 :     ABI_SFREE(self%cols)
     223         [ +  - ]:           3 :     ABI_SFREE(self%kpts)
     224         [ +  - ]:           3 :     ABI_SFREE(self%kweights)
     225         [ +  - ]:           3 :     ABI_SFREE(self%Amnk)
     226         [ +  - ]:           3 :     ABI_SFREE(self%psi_wann_k)
     227         [ +  - ]:           3 :     ABI_SFREE(self%Hwannk)
     228         [ +  - ]:           3 :     ABI_SFREE(self%Rlist)
     229         [ +  - ]:           3 :     ABI_SFREE(self%wannR)
     230         [ +  - ]:           3 :     ABI_SFREE(self%HwannR)
     231         [ +  - ]:           3 :     ABI_SFREE(self%exclude_bands)
     232                 :           5 :     select case (self%method)
     233                 :             :     case(1)
     234         [ +  - ]:           2 :        ABI_SFREE(self%anchor_kpt)
     235         [ +  - ]:           2 :        ABI_SFREE(self%anchor_ibands)
     236         [ +  - ]:           2 :        ABI_SFREE(self%projectors)
     237                 :             :     case(2)
     238   [ +  +  -  +  :           3 :        ABI_SFREE(self%projectors)
                      - ]
     239                 :             :     end select
     240                 :           3 :   end subroutine finalize
     241                 :             : 
     242                 :           0 :   function get_psi_k(self, ikpt) result(psik)
     243                 :             :     class(WannierBuilder_t), intent(inout):: self
     244                 :             :     integer, intent(in):: ikpt
     245                 :             :     complex(dp),  pointer:: psik(:, :)
     246                 :           0 :     ABI_UNUSED_A(self)
     247                 :           0 :     ABI_UNUSED_A(ikpt)
     248                 :           0 :     ABI_UNUSED_A(psik)
     249                 :           0 :     ABI_ERROR("WannierBuilder_t%get_psi_k should be overrided!")
     250                 :           0 :   end function get_psi_k
     251                 :             : 
     252                 :             : 
     253                 :           0 :   function get_evals_k(self, ikpt) result(ek)
     254                 :             :     class(WannierBuilder_t), intent(inout):: self
     255                 :             :     integer, intent(in):: ikpt
     256                 :             :     real(dp),  pointer:: ek(:)
     257                 :           0 :     ABI_UNUSED_A(self)
     258                 :           0 :     ABI_UNUSED_A(ikpt)
     259                 :           0 :     ABI_UNUSED_A(ek)
     260                 :           0 :     ABI_ERROR("WannierBuilder_t%get_evals_k should be overrided")
     261                 :           0 :   end function get_evals_k
     262                 :             : 
     263                 :             : 
     264                 :             :   ! automatically set the anchor points using the weight functions.
     265                 :             :   ! The bands with the largest weights are selected as the anchor points.
     266                 :           0 :   subroutine auto_find_anchors(self, ianchors)
     267                 :             :     class(WannierBuilder_t), intent(inout):: self
     268                 :             :     integer, intent(out):: ianchors(self%nwann)
     269                 :             :     integer:: i
     270                 :           0 :     real(dp):: weights(self%nband)
     271                 :           0 :     integer:: order(self%nband)
     272                 :             : 
     273                 :             :     call self%get_weight(self%anchor_ikpt, self%disentangle_func_type, &
     274                 :           0 :          & self%mu, self%sigma, weights, project_to_anchor=.False.)
     275                 :           0 :     call insertion_sort_double(weights, order)
     276                 :             : 
     277         [ #  # ]:           0 :     do i = 1, self%nwann
     278                 :           0 :        ianchors(i)= order(self%nband-i+1)
     279                 :             :     end  do
     280                 :           0 :   end subroutine auto_find_anchors
     281                 :             : 
     282   [ -  +  +  -  :           2 :   subroutine set_anchor(self, anchor_kpt, anchor_ibands)
             +  -  -  + ]
     283                 :             :     !> anchor_kpt: anchor kpoint (optional).
     284                 :             :     !> anchor_ibands: the indices of mode used as anchor points (optional).
     285                 :             :     class(WannierBuilder_t), intent(inout):: self
     286                 :             :     real(dp), intent(in) ::  anchor_kpt(:)
     287                 :             :     integer, optional, intent(in):: anchor_ibands(:)
     288                 :           2 :     complex(dp), pointer :: psik(:,:)
     289                 :             :     character(len = 500):: msg
     290                 :             :     integer :: i
     291   [ +  -  +  -  :           6 :     ABI_MALLOC(self%anchor_ibands, (self%nwann))
          +  -  -  +  -  
                +  -  + ]
     292   [ -  +  +  -  :           6 :     ABI_MALLOC(self%anchor_kpt, (size(anchor_kpt)))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     293   [ -  +  +  -  :           8 :     ABI_MALLOC(self%projectors, (self%nbasis, self%nwann))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
     294   [ +  -  -  +  :          10 :     self%anchor_kpt = anchor_kpt
             -  -  +  + ]
     295                 :           2 :     self%anchor_ikpt = self%find_kpoint(anchor_kpt)
     296                 :             : 
     297         [ -  + ]:           2 :     if (.not. present(anchor_ibands)) then
     298                 :           0 :        call wrtout( std_out, "Anchor points not specified, finding atomatically")
     299                 :           0 :        call self%auto_find_anchors( self%anchor_ibands)
     300         [ -  + ]:           2 :     else if (.not. size(anchor_ibands) == self%nwann) then
     301                 :           0 :        ABI_ERROR("The number of anchor points should be equal to the number of Wannier functions.")
     302                 :             :     else
     303   [ +  -  -  +  :          10 :        self%anchor_ibands = anchor_ibands
             -  -  +  + ]
     304                 :             :     end if
     305         [ +  - ]:           2 :     write(msg, "(2a)") "Anchor point band indices set to ", trim(ltoa(self%anchor_ibands))
     306         [ +  + ]:           6 :     call wrtout([ab_out, std_out], msg )
     307                 :           2 :     psik=> self%get_psi_k(self%anchor_ikpt)
     308         [ +  + ]:           8 :     do i = 1, self%nwann
     309         [ +  + ]:          98 :         self%projectors(:, i)=psik(:, self%anchor_ibands(i))
     310                 :             :   end do
     311         [ -  + ]:           2 :   end subroutine set_anchor
     312                 :             : 
     313                 :             : 
     314         [ -  + ]:           1 :   subroutine set_disp_projector(self, id_projectors)
     315                 :             :     class(WannierBuilder_t), intent(inout):: self
     316                 :             :     integer, intent(in):: id_projectors(:)
     317                 :             :     integer:: i
     318   [ -  +  +  -  :           4 :     ABI_MALLOC(self%projectors, (self%nbasis, self%nwann))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
     319   [ +  +  +  + ]:          49 :     self%projectors(:,:)=zero
     320         [ +  + ]:           4 :     do i = 1, self%nwann
     321                 :           4 :        self%projectors(id_projectors(i), i)= cmplx(1.0, 0.0, dp)
     322                 :             :     end do
     323                 :           1 :   end subroutine  set_disp_projector
     324                 :             : 
     325                 :           0 :   subroutine set_mode_projector(self, kpoint, iband)
     326                 :             :     class(WannierBuilder_t), intent(inout):: self
     327                 :             :     real(dp), intent(in):: kpoint(:)
     328                 :             :     integer:: iband(:)
     329                 :           0 :     ABI_UNUSED_A(self)
     330                 :             :     ABI_UNUSED(kpoint)
     331                 :             :     ABI_UNUSED(iband)
     332                 :           0 :   end subroutine  set_mode_projector
     333                 :             : 
     334                 :             : 
     335                 :           2 :   subroutine select_columns(self)
     336                 :             :     class(WannierBuilder_t), intent(inout):: self
     337                 :             :     integer::  iband
     338                 :           4 :     complex(dp):: psi_dagger(self%nband, self%nbasis)
     339                 :           4 :     complex(dp):: psi_dagger_copy(self%nband, self%nbasis)
     340                 :           4 :     real(dp):: weight(self%nband)
     341                 :             :     !real(dp), pointer:: evals_anchor(:)
     342                 :             :     !type(eigensolver):: esolver
     343                 :             :     character(len = 500):: msg
     344                 :             :     ! find anchor points, by default gamma
     345                 :           2 :     self%anchor_ikpt = self%find_kpoint(self%anchor_kpt)
     346                 :             :     ! TODO: add qpt if anchor_ikpt is not found
     347                 :             :     !
     348                 :             :     !if (size(self%anchor_ibands) /= 0) then
     349                 :             :     !
     350                 :             :     !end if
     351                 :             :     ! calculate weight matrix for each kpoint
     352                 :             :     call self%get_weight(self%anchor_ikpt, self%disentangle_func_type, self%mu, self%sigma, weight, &
     353                 :           2 :             &project_to_anchor = .True.)
     354                 :             :            ! &project_to_anchor = self%project_to_anchor)
     355                 :             : 
     356                 :             :     ! at anchor-kpoint, find cols
     357                 :             :     ! psi: (ibasis, iband)
     358   [ +  +  +  + ]:         482 :     psi_dagger = transpose(conjg(self%get_psi_k(self%anchor_ikpt)))
     359         [ +  + ]:          32 :     do iband = 1, self%nband
     360         [ +  + ]:         482 :        psi_dagger(iband, :) = psi_dagger(iband, :)*weight(iband)
     361                 :             :     end do
     362   [ +  +  +  + ]:         482 :     psi_dagger_copy(:,:) = psi_dagger(:,:)
     363                 :           2 :     call self%get_columns(psi_dagger_copy, self%cols)
     364         [ +  - ]:           2 :     write(msg, '(2a) ') 'Columns selected: ', trim(ltoa(self%cols))
     365         [ +  + ]:           6 :     call wrtout([ab_out, std_out], msg )
     366                 :             : 
     367                 :             :     !psi_dagger_copy(:,:) = psi_dagger(:,:)
     368                 :             :     !! check the eigen values:
     369                 :             :     !call self%get_Amnk(self%anchor_ikpt, Amn)
     370                 :             :     !! print the anchor point eigen values:
     371                 :             :     !evals_anchor => self%get_evals_k(self%anchor_ikpt)
     372                 :             :     !call Amn_to_H_from_evals(Amn, evals_anchor, &
     373                 :             :     !    & self%nwann, self%nband, Hwann)
     374                 :             :     !evals = evals_anchor(self%anchor_ibands)
     375                 :             :     !write(msg, '(2a)') "The eigen values of the anchor points: ", &
     376                 :             :     !     & trim(ltoa(evals))
     377                 :             :     !call wrtout([ab_out, std_out], msg )
     378                 :             :     !! calculate the eigen values of the Hwannk at anchor point
     379                 :             :     !call esolver%run(evals, Hwann)
     380                 :             :     !write(msg, '(2a)') "The eigen values of Hwann(k_anchor):   ", &
     381                 :             :     !     & trim(ltoa(evals))
     382                 :             :     !call wrtout([ab_out, std_out], msg )
     383                 :             :     !call esolver%finalize()
     384                 :           2 :   end subroutine select_columns
     385                 :             : 
     386                 :           3 :   subroutine construct_wannier(self)
     387                 :             :     class(WannierBuilder_t), intent(inout):: self
     388                 :             :     integer:: ikpt
     389                 :           3 :     complex(dp), pointer:: p(:, :)
     390                 :             :     !real(dp):: weight(self%nband)
     391                 :             : 
     392                 :             :     !complex(dp):: tmp(self%nwann, self%nwann)
     393                 :             :     !real(dp):: evals(self%nwann)
     394                 :             :     !type(eigensolver):: esolver
     395                 :             : 
     396                 :           3 :     if(self%method == 1)then
     397                 :           2 :        call self%select_columns()
     398                 :             :     end if
     399                 :             : 
     400                 :             :     ! For each kpoint, calculate Amn matrix, wannier function, and Hk at k
     401         [ +  + ]:         195 :     do ikpt = 1, self%nkpt
     402                 :             :        !Amnk (nband, nwann, nkpt)
     403                 :         192 :        p => self%get_psi_k(ikpt)
     404                 :         192 :        call self%get_Amnk(ikpt, self%Amnk(:, :, ikpt))
     405                 :             :        ! psik*Amnk
     406   [ +  -  +  +  :      796416 :        self%psi_wann_k(:, :, ikpt) = matmul(p, self%Amnk(:, :, ikpt))
          +  +  +  +  +  
          +  +  +  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
             -  -  -  - ]
     407                 :             :        call Amn_to_H_from_evals(self%Amnk(:, :, ikpt), self%get_evals_k(ikpt), &
     408         [ -  + ]:         195 :              self%nwann, self%nband, self%Hwannk(:, :, ikpt))
     409                 :             :          !tmp = self%Hwannk(:,:,ikpt)
     410                 :             :          !call esolver%run(evals, tmp)
     411                 :             :          !call esolver%finalize()
     412                 :             :        !print *, "ev1:", self%get_evals_k(ikpt)
     413                 :             :       ! print *, "ev2:",evals
     414                 :             : 
     415                 :             :     end do
     416                 :             :     ! Fourier transform of wannier function to real space
     417                 :           3 :     call self%get_wannR_and_HwannR(self%Rlist)
     418         [ +  + ]:           3 :   end subroutine construct_wannier
     419                 :             : 
     420                 :             : 
     421                 :             : 
     422                 :           0 :   subroutine run_all(self, ncfilename, Amnkfilename)
     423                 :             :     class(WannierBuilder_t), intent(inout):: self
     424                 :             :     character(*), intent(in):: ncfilename
     425                 :             :     character(*), intent(in):: Amnkfilename
     426                 :             :     type(IOWannNC):: ncfile
     427                 :           0 :     call self%construct_wannier()
     428                 :           0 :     call self%create_ncfile(ncfilename, ncfile)
     429                 :             :     call self%write_wann_netcdf( ncfile,   &
     430                 :           0 :         &wannR_unit='dimensionless', HwannR_unit='eV')
     431                 :           0 :     call self%close_ncfile(ncfile)
     432         [ #  # ]:           0 :     call self%write_Amnk_w90(trim(Amnkfilename))
     433                 :           0 :   end subroutine run_all
     434                 :             : 
     435                 :             :   !subroutine remove_phase(self, psip)
     436                 :             :   !    class(WannierBuilder_t), intent(inout):: self
     437                 :             :   !    complex(dp), intent(in):: psip(:, :, :) ! (ibasis, iband, ikpt)
     438                 :             :   !    !complex(dp), intent(out):: psi(:,:,:) ! (ibasis, iband, ikpt)
     439                 :             :   !    integer:: ikpt, ibasis
     440                 :             :   !    complex(dp):: phase
     441                 :             :   !    do ikpt = 1, self%nkpt
     442                 :             :   !        do ibasis = 1, self%nbasis
     443                 :             :   !            phase = exp(-tpi_im*dot_product(self%kpts(:, ikpt), self%positions_red(:, ibasis)))
     444                 :             :   !            self%psi(ibasis, :, ikpt) = psip(ibasis, :, ikpt)*phase
     445                 :             :   !        end do
     446                 :             :   !    end do
     447                 :             :   !end subroutine remove_phase
     448                 :             : 
     449                 :             :   !===============================================================
     450                 :             :   ! Find one kpoint in a list of kpoints.
     451                 :             :   !> @
     452                 :             :   !===============================================================
     453         [ -  + ]:           4 :   function find_kpoint(self, kpoint) result(ik)
     454                 :             :     class(WannierBuilder_t), intent(inout):: self
     455                 :             :     real(dp), intent(in):: kpoint(:)
     456                 :             :     integer:: ik, nk
     457                 :             :     integer:: i
     458                 :           8 :     real(dp):: a(size(self%kpts, 2))
     459                 :           4 :     nk = size(self%kpts, 2)
     460                 :             :     ! should transfer back to 1st BZ?
     461         [ +  + ]:         260 :     do i = 1, nk
     462         [ +  + ]:        1028 :        a(i) = sum((self%kpts(:, i) - kpoint)**2)
     463                 :             :     end do
     464                 :             : 
     465   [ +  -  +  -  :         264 :     ik = minloc(a, dim = 1)
          -  -  +  +  -  
                      + ]
     466         [ -  + ]:           4 :     if (a(ik) > 0.001) then
     467                 :           0 :        ABI_ERROR("Error in finding kpoint from kpoint list. ")
     468                 :             :     end if
     469                 :           4 :   end function find_kpoint
     470                 :             : 
     471                 :             :   !===============================================================
     472                 :             :   ! Calculate the weight function for each mode described by iband and ikpt
     473                 :             :   ! The
     474                 :             :   !> @
     475                 :             :   !===============================================================
     476                 :         194 :   subroutine get_weight(self, ikpt, disentanglement, mu, sigma, weight, project_to_anchor)
     477                 :             :     class(WannierBuilder_t), intent(inout):: self
     478                 :             :     integer, intent(in):: ikpt, disentanglement
     479                 :             :     real(dp), intent(in):: mu, sigma
     480                 :             :     real(dp), intent(inout):: weight(self%nband)
     481                 :             :     logical,  intent(in):: project_to_anchor
     482                 :             : 
     483                 :             :     integer:: iband, ianchor
     484                 :             :     real(dp):: proj
     485                 :             :     complex(dp):: p
     486                 :         194 :     real(dp), pointer:: ek(:)
     487                 :         194 :     complex(dp), pointer:: psik(:,:)
     488                 :             : 
     489                 :         388 :     ek => self%get_evals_k(ikpt)
     490                 :         194 :     select case (disentanglement)
     491                 :             :     case (1)
     492         [ +  + ]:        1040 :        weight(:) = 1.0
     493                 :             :     case (2)
     494         [ +  + ]:        2064 :        do iband = 1, self%nband
     495                 :        2064 :           weight(iband) = fermi(ek(iband), mu, sigma)
     496                 :             :        end do
     497                 :             :     case (3)
     498         [ #  # ]:           0 :        do iband = 1, self%nband
     499                 :           0 :           weight(iband) = gaussian(ek(iband), mu, sigma)
     500                 :             :        end do
     501                 :             :     case default
     502   [ +  +  -  - ]:         194 :        ABI_ERROR("The disentanglement function type can only be 1:unity, 2: fermi, 3: gaussian")
     503                 :             :     end select
     504                 :             : 
     505                 :             :     ! weight_mk *=\sum_anchor < psi_anchor | psi mk>
     506                 :             : 
     507         [ +  + ]:         194 :     if( project_to_anchor) then
     508         [ +  - ]:         130 :       if (size(self%anchor_ibands) /= 0) then
     509                 :         130 :       psik=>self%get_psi_k(ikpt)
     510         [ +  + ]:        2080 :         do iband = 1, self%nband
     511                 :        1950 :              proj = 0.0_dp
     512         [ +  + ]:        7800 :              do ianchor = 1, size(self%anchor_ibands)
     513         [ +  + ]:       93600 :                p = dot_product(self%projectors(:, ianchor), psik(:, iband))
     514                 :        7800 :                proj = proj+real(conjg(p)*p)
     515                 :             :              end do
     516                 :        2080 :             weight(iband) = weight(iband)*proj
     517                 :             :           end do
     518                 :             :        end if
     519                 :             :    end if
     520                 :         194 :   end subroutine get_weight
     521                 :             : 
     522         [ -  + ]:           2 :   subroutine get_columns(self, psi_dagger, cols)
     523                 :             :     class(WannierBuilder_t), intent(inout):: self
     524                 :             :     complex(dp), intent(in):: psi_dagger(:, :)
     525                 :           4 :     integer:: piv(size(psi_dagger, 2))
     526                 :             :     integer, intent(inout):: cols(self%nwann)
     527                 :           2 :     call complex_QRCP_piv_only(psi_dagger, piv)
     528         [ +  + ]:           8 :     cols = piv(:self%nwann)
     529                 :           2 :   end subroutine get_columns
     530                 :             : 
     531                 :         192 :   subroutine get_Amnk(self, ikpt, Amnk)
     532                 :             :     class(WannierBuilder_t), intent(inout):: self
     533                 :             :     integer, intent(in):: ikpt
     534                 :             :     complex(dp), intent(inout):: Amnk(self%nband, self%nwann)
     535         [ +  + ]:         192 :     if(self%method == 1) then
     536                 :         128 :        call self%get_scdm_Amnk(ikpt, Amnk)
     537         [ +  - ]:          64 :     else if(self%method == 2) then
     538                 :          64 :        call self%get_projected_Amnk(ikpt, Amnk)
     539                 :             :     end if
     540                 :         192 :   end subroutine get_Amnk
     541                 :             : 
     542                 :         128 :   subroutine get_scdm_Amnk(self, ikpt, Amnk)
     543                 :             :     class(WannierBuilder_t), intent(inout):: self
     544                 :             :     integer, intent(in):: ikpt
     545                 :         256 :     complex(dp):: psi_dagger(self%nband, self%nbasis)
     546                 :             :     complex(dp), intent(inout):: Amnk(self%nband, self%nwann)
     547                 :         256 :     real(dp):: weight(self%nband)
     548                 :         256 :     complex(dp):: U(self%nband, self%nwann), VT(self%nwann, self%nwann)
     549                 :         256 :     real(dp):: S(self%nband)
     550                 :             :     !real(dp):: weights(self%nband)
     551                 :             :     integer:: iband
     552                 :         128 :     complex(dp),  pointer:: p(:, :)
     553                 :             : 
     554                 :             :     call self%get_weight(ikpt, self%disentangle_func_type, self%mu, self%sigma, weight, &
     555                 :         128 :          &project_to_anchor = self%project_to_anchor)
     556                 :             : 
     557                 :         128 :     p => self%get_psi_k(ikpt)
     558         [ +  + ]:        2048 :     do iband = 1, self%nband
     559         [ +  + ]:       30848 :        psi_dagger(iband, :) = conjg(p(:, iband)) *weight(iband)
     560                 :             :     end do
     561                 :             : 
     562                 :             :     ! orthogonalize selected columns
     563   [ +  -  +  +  :        6272 :     call complex_svd(psi_dagger(:, self%cols), U, S, VT, 'S')
                   +  + ]
     564   [ +  -  +  +  :       25344 :     Amnk(:, :) = matmul(U, VT)
          +  +  +  +  +  
                +  +  + ]
     565                 :         128 :   end subroutine get_scdm_Amnk
     566                 :             : 
     567                 :             : 
     568                 :          64 :   subroutine get_projected_Amnk(self, ikpt, Amnk)
     569                 :             :     class(WannierBuilder_t), intent(inout):: self
     570                 :             :     integer, intent(in):: ikpt
     571                 :             :     complex(dp), intent(inout):: Amnk(self%nband, self%nwann)
     572                 :         128 :     complex(dp):: U(self%nband, self%nwann), VT(self%nwann, self%nwann)
     573                 :         128 :     real(dp):: S(self%nband), weights(self%nband)
     574                 :             :     integer:: iband, iwann
     575                 :          64 :     complex(dp), pointer:: psi(:, :)
     576                 :             : 
     577                 :         128 :     psi => self%get_psi_k(ikpt)
     578                 :             :     call self%get_weight(ikpt, self%disentangle_func_type, &
     579                 :          64 :          & self%mu, self%sigma, weights, project_to_anchor=.False.)
     580                 :             : 
     581                 :             :     ! <proj||psi> * weight
     582         [ +  + ]:        1024 :     do iband = 1, self%nband
     583         [ +  + ]:        3904 :        do iwann = 1, self%nwann
     584                 :             :           !Amnk(iband, iwann)= dot_product(conjg(self%projectors(:, iwann)), psi(:, iband )) * weights(iband)
     585                 :             :           !Amnk(iband, iwann)= dot_product(self%projectors(:, iwann), conjg(psi(:, iband ))) * weights(iband)
     586         [ +  + ]:       47040 :           Amnk(iband, iwann)= dot_product(self%projectors(:, iwann), psi(:, iband )) * weights(iband)
     587                 :             :        end do
     588                 :             :     end do
     589                 :          64 :     call complex_svd(Amnk, U, S, VT, 'S')
     590   [ +  -  +  +  :       12672 :     Amnk(:, :) = matmul(U, VT)
          +  +  +  +  +  
                +  +  + ]
     591                 :          64 :   end subroutine get_projected_Amnk
     592                 :             : 
     593                 :             : 
     594         [ -  + ]:           3 :   subroutine get_wannR_and_HwannR(self, Rlist)
     595                 :             :     class(WannierBuilder_t), intent(inout):: self
     596                 :             :     integer, intent(in):: Rlist(:, :)
     597                 :             :     !complex(dp), intent(out):: HR(self%nwann, self%nwann, size(Rlist, 2))
     598                 :             :     !-- H(R)= \sum_k H(k) * exp(i2pi k.R)
     599                 :             :     integer:: ik, iR, nR
     600                 :             :     complex(dp):: factor
     601                 :           3 :     nR = size(Rlist, 2)
     602   [ -  +  +  -  :          15 :     ABI_MALLOC(self%HwannR, (self%nwann, self%nwann, nR))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
     603   [ -  +  +  -  :          15 :     ABI_MALLOC(self%WannR, (self%nbasis, self%nwann, nR))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
     604                 :             : 
     605   [ +  +  +  +  :        2499 :     self%HwannR(:, :, :) = cmplx(0.0, 0.0, dp)
                   +  + ]
     606   [ +  +  +  +  :        9411 :     self%wannR(:, :, :) = cmplx(0.0, 0.0, dp)
                   +  + ]
     607         [ +  + ]:         195 :     do ik = 1, self%nkpt
     608         [ +  + ]:       12483 :        do iR = 1, nR
     609         [ +  + ]:       49152 :           factor = exp(-tpi_Im*dot_product(self%kpts(:, ik), Rlist(:, iR))) * self%kweights(ik)
     610   [ +  +  +  + ]:      159744 :           self%HwannR(:, :, iR) = self%HwannR(:,:, iR) + self%Hwannk(:, :, ik)*factor
     611   [ +  +  +  + ]:      602304 :           self%wannR(:, :, iR) = self%wannR(:,:, iR) + self%psi_wann_k(:, :, ik)*factor
     612                 :             :        end do
     613                 :             :     end do
     614                 :           3 :   end subroutine get_wannR_and_HwannR
     615                 :             : 
     616                 :         192 :   subroutine Amn_to_H_from_evals(Amn, evals, nwann, nband, Hwann)
     617                 :             :     integer, intent(in)::  nwann, nband
     618                 :             :     complex(dp), intent(in):: Amn(nband, nwann)
     619                 :             :     real(dp), intent(in):: evals(nband)
     620                 :             :     complex(dp), intent(inout):: Hwann(nwann, nwann)
     621                 :             :     integer:: i
     622                 :         384 :     complex(dp):: tmp(nwann, nband)
     623                 :             : 
     624                 :             :     ! A\dagger E
     625         [ +  + ]:        3072 :     do i = 1, nband
     626         [ +  + ]:       11712 :        tmp(:, i) = conjg(Amn(i, :))*evals(i)
     627                 :             :     end do
     628                 :             :     ! Hwann = A\dagger @ E @ A
     629   [ +  -  +  +  :       38016 :     Hwann = matmul(tmp, Amn)
          +  +  +  +  +  
                +  +  + ]
     630                 :         192 :   end subroutine Amn_to_H_from_evals
     631                 :             : 
     632   [ #  #  #  #  :           0 :   subroutine Amn_to_H(Amn, psi, H0, nbasis, nwann, Hwann)
             #  #  #  # ]
     633                 :             :     ! Hwann = psi\dagger A
     634                 :             :     complex(dp), intent(in):: Amn(:, :), psi(:, :), H0(:, :)
     635                 :             :     complex(dp), intent(inout):: Hwann(:, :)
     636                 :             :     integer, intent(in):: nbasis, nwann
     637                 :           0 :     complex(dp):: tmp(nbasis, nwann)
     638                 :             :     !Hwann = A_dagger@psi_dagger@H0@psi@A
     639   [ #  #  #  #  :           0 :     tmp(:, :) = matmul(psi, Amn)
          #  #  #  #  #  
                #  #  # ]
     640   [ #  #  #  #  :           0 :     Hwann = matmul(matmul(transpose(conjg(tmp)), H0), tmp)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
     641                 :           0 :   end subroutine Amn_to_H
     642                 :             : 
     643                 :           0 :   subroutine write_Amnk_w90(self, fname)
     644                 :             :     ! write to Amnk file
     645                 :             :     class(WannierBuilder_t), intent(inout):: self
     646                 :             :     character(len=*), intent(in):: fname
     647                 :             :     integer:: iwann, iband, ikpt, locibnd
     648                 :             :     integer:: iun_amn
     649                 :             :     character(len=500):: msg
     650                 :             : 
     651         [ #  # ]:           0 :     if (open_file(trim(fname)//".amn", msg, newunit=iun_amn, &
     652                 :             :          & form="formatted", status="unknown", action="write") /= 0) then
     653                 :           0 :        ABI_ERROR(msg)
     654                 :             :     end if
     655                 :             : 
     656                 :             : 
     657                 :             :     !IF (wan_mode=='standalone') THEN
     658                 :             :     !   iun_amn = find_free_unit()
     659                 :             :     !   IF (ionode) OPEN (unit = iun_amn, file = trim(seedname)//".amn",form='formatted')
     660                 :             :     !ENDIF
     661                 :             : 
     662                 :             :     !TODO: re-enable this.
     663                 :             :     !WRITE(stdout, '(a, i8)') '  AMN: iknum = ',iknum
     664                 :             :     !
     665                 :             :     !IF (wan_mode=='standalone') THEN
     666                 :             :     !   CALL date_and_tim( cdate, ctime )
     667                 :             :     !   header='Created on '//cdate//' at '//ctime//' with SCDM '
     668                 :             :     !   IF (ionode) THEN
     669                 :             :     !      WRITE (iun_amn, *) header
     670                 :             :     !      WRITE (iun_amn, '(3i8, xxx, 2f10.6)') numbands,  iknum, n_wannier, scdm_mu, scdm_sigma
     671                 :             :     !   ENDIF
     672                 :             :     !ENDIF
     673                 :             : 
     674         [ #  # ]:           0 :     do ikpt = 1, self%nkpt
     675         [ #  # ]:           0 :        do iwann = 1, self%nwann
     676                 :           0 :           locibnd = 0
     677         [ #  # ]:           0 :           do iband = 1, self%nband
     678                 :             :              !IF (excluded_band(iband)) CYCLE
     679                 :           0 :              locibnd = locibnd+1
     680                 :           0 :              WRITE (iun_amn, '(3i5, 2f18.12)') locibnd, iwann, ikpt, &
     681                 :           0 :                   & REAL(self%Amnk(locibnd, iwann, ikpt)), &
     682                 :           0 :                   & AIMAG(self%Amnk(locibnd, iwann, ikpt))
     683                 :             :           end do
     684                 :             :        end do
     685                 :             :     end do
     686                 :           0 :     close (iun_amn)
     687                 :           0 :   end subroutine write_Amnk_w90
     688                 :             : 
     689   [ #  #  #  # ]:           0 :   subroutine write_Hwann_w90(self, HR, Rlist, fname)
     690                 :             :     class(WannierBuilder_t), intent(inout):: self
     691                 :             :     complex(dp), intent(in):: HR(:, :, :)
     692                 :             :     integer, intent(in):: Rlist(:, :)
     693                 :             :     character(len=*), intent(in):: fname
     694                 :             :     integer:: iR, ifile, iwann1, iwann2
     695                 :             :     character(len=500):: msg
     696                 :             : 
     697         [ #  # ]:           0 :     if (open_file(trim(fname)//".hr", msg, newunit=ifile, &
     698                 :             :          & form="formatted", status="unknown", action="write") /= 0) then
     699                 :           0 :        ABI_ERROR(msg)
     700                 :             :     end if
     701                 :             : 
     702                 :             : 
     703         [ #  # ]:           0 :     do iR = 1, size(Rlist, 2)
     704                 :           0 :        WRITE (ifile, '(3i5)') Rlist(:, iR)
     705         [ #  # ]:           0 :        do iwann1 = 1, self%nwann
     706         [ #  # ]:           0 :           do iwann2 = 1, self%nwann
     707                 :           0 :              WRITE (ifile, '(f18.12)') HR(iwann1, iwann2, iR)
     708                 :             :           end do
     709                 :             :        end do
     710                 :             :     end do
     711                 :           0 :     close (ifile)
     712                 :           0 :   end subroutine write_Hwann_w90
     713                 :             : 
     714                 :           3 :   subroutine create_ncfile(self, fname, ncfile)
     715                 :             :     class(WannierBuilder_t), intent(inout):: self
     716                 :             :     type(IOWannNC):: ncfile
     717                 :             :     character(len=*), intent(in):: fname
     718                 :           3 :     ABI_UNUSED_A(self)
     719                 :           3 :     call ncfile%initialize(filename = fname)
     720                 :           3 :   end subroutine create_ncfile
     721                 :             : 
     722                 :           3 :   subroutine close_ncfile(self, ncfile)
     723                 :             :     class(WannierBuilder_t), intent(inout):: self
     724                 :             :     type(IOWannNC):: ncfile
     725                 :           3 :     ABI_UNUSED_A(self)
     726                 :           3 :     call ncfile%close_file()
     727                 :           3 :   end subroutine close_ncfile
     728                 :             : 
     729                 :             : 
     730                 :           3 :   subroutine write_wann_netcdf(self, ncfile, wannR_unit, HwannR_unit)
     731                 :             :     class(WannierBuilder_t), intent(inout):: self
     732                 :             :     character(*), intent(in):: HwannR_unit, wannR_unit
     733                 :             :     type(IOWannNC), intent(inout):: ncfile
     734                 :             :     call ncfile%write_wann( nR = self%nR, ndim = self%nkdim, &
     735                 :             :          & nwann = self%nwann, nbasis = self%nbasis, Rlist = self%Rlist, &
     736                 :             :          & wannR = self%wannR, HwannR = self%HwannR, &
     737                 :           3 :          & wannR_unit = wannR_unit, HwannR_unit = HwannR_unit)
     738                 :             :     call ncfile%write_Amnk(nkpt = self%nkpt, nband = self%nband, nwann = self%nwann, &
     739                 :           3 :          & kpoints = self%kpts, Amnk = self%Amnk)
     740                 :             :     !TODO: add write_eigenvalues
     741                 :           3 :   end subroutine write_wann_netcdf
     742                 :             : 
     743                 :         344 :   subroutine get_wannier_eigen(self, kpoint, evals, evecs)
     744                 :             :     class(WannierBuilder_t), intent(inout):: self
     745                 :             :     real(dp), intent(in) :: kpoint(3)
     746                 :             :     real(dp), intent(inout) :: evals(self%nwann)
     747                 :             :     complex(dp), optional, intent(inout) :: evecs(self%nwann, self%nwann)
     748                 :         688 :     complex(dp) :: Hk(self%nwann, self%nwann), phase
     749                 :         344 :     type(eigensolver):: esolver
     750                 :             :     integer :: iR
     751   [ +  +  +  + ]:        4472 :     Hk(:,:)=0.0_dp
     752         [ +  + ]:       22360 :     do iR=1, self%nR
     753         [ +  + ]:       88064 :        phase = exp(tpi_im * dot_product(kpoint, self%Rlist(:, iR)))
     754   [ +  +  +  + ]:      286552 :        Hk = Hk + self%HwannR(:, :, iR) * phase
     755                 :             :     end do
     756                 :         344 :     call esolver%run(evals, Hk)
     757                 :             :     ! Hk is overwritten as evecs
     758         [ +  - ]:         344 :     if (present(evecs)) then
     759   [ +  +  +  + ]:        4472 :        evecs=Hk
     760                 :             :     end if
     761                 :         344 :     call esolver%finalize()
     762   [ +  -  -  +  :         688 :   end subroutine get_wannier_eigen
                   -  + ]
     763                 :             : 
     764                 :           2 :   subroutine get_wannier_eigen_klist(self, kpoints, nk, evals_nk, evecs_nk)
     765                 :             :     class(WannierBuilder_t), intent(inout):: self
     766                 :             :     integer, intent(in) :: nk
     767                 :             :     real(dp), intent(in) :: kpoints(3, nk)
     768                 :             :     real(dp), intent(inout) :: evals_nk(self%nwann, nk)
     769                 :             :     complex(dp), optional, intent(inout) :: evecs_nk(self%nwann, self%nwann, nk)
     770                 :             :     integer :: ik
     771         [ +  + ]:         346 :     do ik =1, nk
     772         [ +  - ]:         346 :        if (present(evecs_nk)) then
     773                 :             :           call self%get_wannier_eigen(kpoints(:, ik), &
     774                 :         344 :                & evals_nk(:, ik), evecs_nk(:,:, ik))
     775                 :             :        else
     776                 :           0 :           call self%get_wannier_eigen(kpoints(:, ik), evals_nk(:, ik))
     777                 :             :        end if
     778                 :             :     end do
     779         [ +  - ]:           2 :   end subroutine get_wannier_eigen_klist
     780                 :             : 
     781                 :             : 
     782                 :             : !============================   WannierBuilder_witheigen_t   =========================
     783                 :             : 
     784   [ -  +  -  + ]:           3 : subroutine set_eigen(self,  evals, psi)
     785                 :             :   class(WannierBuilder_witheigen_t) :: self
     786                 :             :   real(dp), intent(in), target:: evals(:, :)   !(iband, ikpt)
     787                 :             :   complex(dp), intent(in), target:: psi(:, :, :) ! (ibasis, iband, ikpt)
     788                 :           3 :   self%psi => psi
     789                 :           3 :   self%evals => evals
     790                 :           3 : end subroutine set_eigen
     791                 :             : 
     792                 :         386 : function get_evals_k_from_eigen(self, ikpt) result(ek)
     793                 :             :   class(WannierBuilder_witheigen_t), intent(inout):: self
     794                 :             :   integer, intent(in):: ikpt
     795                 :             :   real(dp), pointer:: ek(:)
     796                 :         386 :   ek => self%evals( :, ikpt)
     797                 :         386 : end function get_evals_k_from_eigen
     798                 :             : 
     799                 :             : 
     800                 :         518 : function get_psi_k_from_eigen(self, ikpt) result(psik)
     801                 :             :   class(WannierBuilder_witheigen_t), intent(inout):: self
     802                 :             :   integer, intent(in):: ikpt
     803                 :             :   complex(dp),  pointer:: psik(:, :)
     804                 :         518 :   psik => self%psi(:, :, ikpt)
     805                 :         518 : end function get_psi_k_from_eigen
     806                 :             : 
     807                 :             : 
     808   [ #  #  #  #  :           0 : end module m_wannier_builder
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     809                 :             : !!***
        

Generated by: LCOV version 2.3-1