LCOV - code coverage report
Current view: top level - diagonalization - eigen_diag.F90 (source / functions) Coverage Total Hit
Test: FLEUR test coverage Lines: 63.6 % 33 21
Test Date: 2026-07-15 06:05:57 Functions: 100.0 % 2 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_eigen_diag
       8              :    !! Module provides the high level entry point for solving a generalized eigenvalue problem
       9              :    !! The solver actually used is determined by a call to [[select_solver]] from [[m_available_solvers]].
      10              :    use m_juDFT
      11              :    use m_available_solvers
      12              :    use m_types_mpimat
      13              :    use m_types_mat
      14              :    use m_types_solver
      15              :    use m_lapack
      16              :    implicit none
      17              :    private
      18              :    public :: eigen_diag
      19              : 
      20              : contains
      21              : 
      22         7102 :    subroutine eigen_diag(hmat, smat, ne, eig, ev, ikpt)
      23              :       !! Solve generalized eigenvalue problem
      24              : #ifdef CPP_MPI
      25              :       use mpi
      26              : #endif
      27              :       implicit none
      28              :       class(t_mat), intent(INOUT) :: smat, hmat !! overlapp matrix and Hamiltonian
      29              :       class(t_mat), allocatable, intent(OUT)   :: ev         !! eigenvectors
      30              :       integer, intent(INOUT) :: ne         !! number of eigenpairs searched (and found) on this node
      31              :       !!   on input, overall number of eigenpairs searched,
      32              :       !!   on output, local number of eigenpairs found
      33              :       real, intent(OUT)   :: eig(:)     !! eigenvalues (must be allocated to size ne before)
      34              :       integer, intent(IN) :: ikpt     !! The index of the k-point, just to have more information for debugging
      35              : 
      36              :       !Locals
      37              :       logical                       :: parallel
      38        14204 :       class(t_solver), allocatable   :: solver, transform
      39              : 
      40              :       select type (smat)
      41              :       class IS (t_mpimat)
      42              : #ifdef CPP_MPI
      43         4592 :          parallel = smat%blacsdata%mpi_com /= MPI_COMM_SELF
      44              : #endif
      45              :       class default
      46         2510 :          parallel = .false.
      47              :       end select
      48              : 
      49              :       call select_solver(parallel, diag_solver=solver, diag_transform=transform)
      50              : 
      51         7102 :       if (.not. allocated(transform)) then
      52              :          ! We solve directly the generalized eigenvalue problem
      53         7102 :          if (solver%generalized) then
      54         7102 :             call timestart("Diagonalization")
      55         7102 :             call solver%solve_gev(hmat, smat, ne, eig, ev, ikpt)
      56         7102 :             call timestop("Diagonalization")
      57         7102 :             call redistribute_ev_to_rowcyclic(ev)
      58              :          else
      59            0 :             call judft_bug("Generalized solver not available?")
      60              :          end if
      61              :       else
      62              :          ! We do a reduction, to a standard problem, then solve the standard problem and transform back
      63            0 :          call timestart("Reduction to S-EVP")
      64            0 :          call transform%to_std(hmat, smat, ne)
      65            0 :          call timestop("Reduction to S-EVP")
      66            0 :          call timestart("Diagonalization")
      67            0 :          print *, "Solver:", solver%name
      68            0 :          call solver%solve_std(hmat, ne, eig, ev)
      69            0 :          call timestop("Diagonalization")
      70            0 :          call timestart("Backtransform of eigenvectors")
      71            0 :          call transform%backtrans(smat, ev)
      72            0 :          call timestop("Backtransform of eigenvectors")
      73            0 :          call redistribute_ev_to_rowcyclic(ev)
      74              :       end if
      75        14204 :    end subroutine
      76              : 
      77         7102 :    subroutine redistribute_ev_to_rowcyclic(ev)
      78              :       class(t_mat), allocatable, intent(inout) :: ev
      79         7102 :       type(t_mpimat) :: row_cyclic_ev
      80              : 
      81              :       select type (ev)
      82              :       type is (t_mpimat)
      83         4592 :          call row_cyclic_ev%init(ev%l_real, ev%global_size1, ev%global_size1, ev%blacsdata%mpi_com, MPIMAT_ROWCYCLIC)
      84         4592 :          call row_cyclic_ev%copy(ev, 1, 1)
      85         4592 :          call ev%free()
      86              :          call ev%init(row_cyclic_ev%l_real, row_cyclic_ev%global_size1, row_cyclic_ev%global_size2, &
      87         4592 :                       row_cyclic_ev%blacsdata%mpi_com, MPIMAT_ROWCYCLIC)
      88         4592 :          call ev%copy(row_cyclic_ev, 1, 1)
      89         9184 :          call row_cyclic_ev%free()
      90              :       class default
      91              :          ! Serial output remains unchanged.
      92              :       end select
      93         7102 :    end subroutine redistribute_ev_to_rowcyclic
      94              : 
      95        14204 : end module m_eigen_diag
        

Generated by: LCOV version 2.0-1