LCOV - code coverage report
Current view: top level - diagonalization - elsi.F90 (source / functions) Coverage Total Hit
Test: FLEUR test coverage Lines: 87.5 % 16 14
Test Date: 2026-06-09 05:02:56 Functions: 66.7 % 3 2

            Line data    Source code
       1              : !-------------------------------------------------------------------------------
       2              : ! Copyright (c) 2025 Peter Grünberg Institut, Forschungszentrum Jülich, Germany
       3              : ! This file is part of FLEUR and available as free software under the conditions
       4              : ! of the MIT license as expressed in the LICENSE file in more detail.
       5              : !--------------------------------------------------------------------------------
       6              : 
       7              : module m_elsi
       8              :    use m_types_solver
       9              :    implicit none
      10              : 
      11              :    type, extends(t_solver)::t_solver_elsi
      12              :    contains
      13              :       procedure        :: solve_gev => elsi_GEV
      14              :    end type
      15              :    public :: get_solver_elsi
      16              : 
      17              : contains
      18              : 
      19           91 :    function get_solver_elsi() result(solver)
      20              :       class(t_solver), allocatable :: solver
      21           91 :       allocate (t_solver_elsi :: solver)
      22           91 :       solver%name = "elsi"
      23              : #ifdef CPP_ELSI
      24              :       solver%available = .true.
      25              : #else
      26           91 :       solver%available = .false.
      27              : #endif
      28           91 :       solver%parallel = .true.
      29           91 :       solver%serial = .true.
      30           91 :       solver%generalized = .true.
      31           91 :       solver%standard = .false.
      32           91 :       solver%single_precision = .false.
      33           91 :       solver%transform = .false.
      34           91 :       solver%GPU = .false.
      35           91 :       solver%use_sp = .false.
      36           91 :    end function
      37              : 
      38            0 :    subroutine elsi_gev(self, hmat, smat, ne, eig, zmat, ikpt)
      39              : 
      40              :       use m_juDFT
      41              :       use m_types_mpimat
      42              :       use m_types_mat
      43              : #ifdef CPP_ELSI
      44              :       use elsi
      45              :       use mpi
      46              : #endif
      47              :       implicit none
      48              :       class(t_solver_elsi)           ::self
      49              :       class(t_mat), intent(INOUT)    :: hmat, smat
      50              :       class(t_mat), allocatable, intent(OUT)::zmat
      51              :       real, intent(out)              :: eig(:)
      52              :       integer, intent(INOUT)         :: ne
      53              :       integer, intent(IN)            :: ikpt
      54              : 
      55              :       integer, parameter             :: solver = 1 !Use 1 for ELPA, 9 for ChASE. See ELSI manual for more solvers.
      56              : 
      57              : #ifdef CPP_ELSI
      58              :       !...  Local variables
      59              :       !
      60              :       integer           :: blk
      61              :       integer, parameter :: BLACS_DENSE = 0
      62              :       type(elsi_handle) :: eh
      63              :       class(t_mat), allocatable :: evec
      64              :       real, allocatable         :: eig_tmp(:)
      65              : 
      66              :       call timestart("ELSI")
      67              : 
      68              :       call hmat%u2l()
      69              :       call smat%u2l()
      70              : 
      71              :       select type (hmat)
      72              :       type IS (t_mpimat)
      73              :          select type (smat)
      74              :          type IS (t_mpimat)
      75              :             if (hmat%blacsdata%blacs_desc(5) == hmat%blacsdata%blacs_desc(6)) then
      76              :                blk = hmat%blacsdata%blacs_desc(5)
      77              :             else
      78              :                call judft_error("BUG: in ELSI the row/column blocksize must be equal")
      79              :             end if
      80              :             call elsi_init(eh, solver, 1, BLACS_DENSE, hmat%global_size1, 1.0*ne, ne)
      81              :             call elsi_set_mpi(eh, hmat%blacsdata%mpi_com)
      82              :             call elsi_set_blacs(eh, hmat%blacsdata%blacs_desc(2), blk)
      83              :             allocate (t_mpimat::evec)
      84              :             call evec%init(hmat)
      85              :             allocate (eig_tmp(hmat%global_size1))
      86              :          class DEFAULT
      87              :             call judft_error("BUG: Inconsistent matrixes in ELSI call")
      88              :          end select
      89              :       type IS (t_mat)
      90              :          select type (smat)
      91              :          type IS (t_mat)
      92              :             call elsi_init(eh, solver, 0, BLACS_DENSE, hmat%matsize1, 1.*ne, ne)
      93              :             allocate (t_mat::evec)
      94              :             call evec%init(hmat)
      95              :             allocate (eig_tmp(hmat%matsize1))
      96              : 
      97              :          class DEFAULT
      98              :             call judft_error("BUG: Inconsistent matrixes in ELSI call")
      99              :          end select
     100              :       end select
     101              :       call timestart("elsi_ev")
     102              : #ifdef _OPENACC
     103              :       call elsi_set_elpa_gpu(eh, 1)
     104              : #endif
     105              :       !Now perform diagonalization
     106              :       call elsi_set_output(eh, 3)
     107              :       call elsi_set_output_unit(eh, 7)
     108              :       call elsi_set_illcond_check(eh, 0)
     109              :       call elsi_reinit(eh)
     110              :       if (hmat%l_real) then
     111              :          call elsi_ev_real(eh, hmat%data_r, smat%data_r, eig_tmp, evec%data_r)
     112              :       else
     113              :          call elsi_ev_complex(eh, hmat%data_c, smat%data_c, eig_tmp, evec%data_c)
     114              :       end if
     115              :       call timestop("elsi_ev")
     116              :       call timestart("set output")
     117              :       !Copy data into correct data structures
     118              :       eig = eig_tmp(:size(eig))
     119              :       select type (evec)
     120              :       type IS (t_mat)
     121              :          allocate (t_mat::zmat)
     122              :          call zmat%init(evec%l_real, evec%matsize1, ne)
     123              :          if (evec%l_real) then
     124              :             zmat%data_r = evec%data_r(:, :ne)
     125              :          else
     126              :             zmat%data_c = evec%data_c(:, :ne)
     127              :          end if
     128              :       type IS (t_mpimat)
     129              :          allocate (t_mpimat::zmat)
     130              :          call zmat%init(evec)
     131              :          call zmat%copy(evec, 1, 1)
     132              : 
     133              :       end select
     134              :       call evec%free()
     135              :       call timestop("set output")
     136              :       call elsi_finalize(eh)
     137              :       call timestop("ELSI")
     138              : 
     139              : #endif
     140            0 :    end subroutine elsi_gev
     141          182 : end module m_elsi
        

Generated by: LCOV version 2.0-1