LCOV - code coverage report
Current view: top level - diagonalization - lapack_singlePrec_diag.F90 (source / functions) Hit Total Coverage
Test: FLEUR test coverage Lines: 0 64 0.0 %
Date: 2024-05-01 04:44:11 Functions: 0 1 0.0 %

          Line data    Source code
       1             : ! Copyright (c) 2018 Peter Grünberg Institut, Forschungszentrum Jülich, Germany
       2             : ! This file is part of FLEUR and available as free software under the conditions
       3             : ! of the MIT license as expressed in the LICENSE file in more detail.
       4             : !
       5             : ! @authors: Miriam Hinzen, Gregor Michalicek
       6             : ! Added MPI implementation, DW 2018
       7             : !--------------------------------------------------------------------------------
       8             : MODULE m_lapack_singlePrec_diag
       9             :   USE m_judft
      10             :   USE m_constants
      11             :   IMPLICIT NONE
      12             :   PRIVATE
      13             :   integer,parameter:: sp=selected_real_kind(6)
      14             :   
      15             :   PUBLIC lapack_singlePrec_diag
      16             : 
      17             : CONTAINS
      18             : 
      19           0 :   SUBROUTINE lapack_singlePrec_diag(hmat,smat,ne,eig,zmat)
      20             : 
      21             :     USE m_types_mat
      22             :     USE m_judft
      23             : 
      24             :     !Simple driver to solve Generalized Eigenvalue Problem using the ChASE library
      25             :     IMPLICIT NONE
      26             : 
      27             :     TYPE(t_mat),               INTENT(INOUT) :: hmat,smat
      28             :     INTEGER,                   INTENT(INOUT) :: ne
      29             :     CLASS(t_mat), ALLOCATABLE, INTENT(OUT)   :: zmat
      30             :     REAL,                      INTENT(OUT)   :: eig(:)
      31             : 
      32             :     INTEGER            :: nev,lwork,liwork
      33             :     INTEGER            :: info
      34             : 
      35             :     
      36             :     
      37           0 :     ALLOCATE(t_mat::zmat)
      38           0 :     CALL zmat%alloc(hmat%l_real,hmat%matsize1,ne)
      39             : 
      40             :     
      41           0 :     IF (hmat%l_real) THEN
      42             : 
      43             :        ! --> start with Cholesky factorization of b ( so that b = l * l^t)
      44             :        ! --> b is overwritten by l
      45           0 :        CALL dpotrf('U',smat%matsize1,smat%data_r,SIZE(smat%data_r,1),info)
      46           0 :        IF (info.NE.0) THEN
      47           0 :           WRITE (*,*) 'Error in dpotrf: info =',info
      48           0 :           CALL juDFT_error("Diagonalization failed",calledby="lapack_singlePrec_diag")
      49             :        ENDIF
      50             : 
      51             :        ! --> now reduce a * z = eig * b * z to the standard form a' * z' = eig * z'
      52             :        ! --> where a' = (l)^-1 * a * (l^t)^-1 and z' = l^t * z
      53           0 :        CALL dsygst(1,'U',smat%matsize1,hmat%data_r,SIZE(hmat%data_r,1),smat%data_r,SIZE(smat%data_r,1),info)
      54           0 :        IF (info.NE.0) THEN
      55           0 :           WRITE (oUnit,*) 'Error in dsygst: info =',info
      56           0 :           CALL juDFT_error("Diagonalization failed",calledby="lapack_singlePrec_diag")
      57             :        ENDIF
      58             : 
      59             :        ! --> solve a' * z' = eig * z' for eigenvalues eig between lb und ub
      60           0 :        BLOCK
      61           0 :         REAL(kind=sp),allocatable:: h(:,:),z(:,:),eigval(:),work(:)
      62           0 :         integer,allocatable      :: iwork(:),ifail(:)
      63           0 :         Allocate(h(size(hmat%data_r,1),size(hmat%data_r,2)))
      64           0 :         Allocate(eigval(size(hmat%data_r,1)),ifail(size(hmat%data_r,1)))
      65           0 :         Allocate(z(size(hmat%data_r,1),ne))
      66           0 :         h=hmat%data_r
      67             : 
      68           0 :         allocate(work(1),iwork(1))
      69           0 :         call ssyevx('V','I','U',size(h,1),h,size(h,1),0.0,0.0,1,ne,0.0,nev,eigval,z,size(z,1),work,-1,iwork,liwork,ifail,info)
      70           0 :         lwork=work(1)
      71           0 :         liwork=iwork(1)
      72           0 :         deallocate(work,iwork)
      73           0 :         allocate(work(lwork),iwork(liwork))
      74             : 
      75           0 :         call ssyevx('V','I','U',size(h,1),h,size(h,1),0.0,0.0,1,ne,0.0,nev,eigval,z,size(z,1),work,lwork,iwork,liwork,ifail,info)
      76             :         
      77           0 :         eig=eigval(:ne)
      78           0 :         zmat%data_r=z(:,:ne)
      79           0 :         deallocate(h,z,eigval,work,iwork)
      80             :        END BLOCK
      81             :        ! --> recover the generalized eigenvectors z by solving z' = l^t * z
      82           0 :        CALL dtrtrs('U','N','N',hmat%matsize1,nev,smat%data_r,smat%matsize1,zMat%data_r,zmat%matsize1,info)
      83           0 :        IF (info.NE.0) THEN
      84           0 :           WRITE (oUnit,*) 'Error in dtrtrs: info =',info
      85           0 :           CALL juDFT_error("Diagonalization failed",calledby="lapack_singlePrec_diag")
      86             :        ENDIF
      87             :        
      88             : 
      89             :     ELSE
      90             : 
      91             :        ! --> start with Cholesky factorization of b ( so that b = l * l^t)
      92             :        ! --> b is overwritten by l
      93           0 :        CALL zpotrf('U',smat%matsize1,smat%data_c,SIZE(smat%data_c,1),info)
      94           0 :        IF (info.NE.0) THEN
      95           0 :           WRITE (*,*) 'Error in zpotrf: info =',info
      96           0 :           CALL juDFT_error("Diagonalization failed",calledby="chase_diag")
      97             :        ENDIF
      98             : 
      99             :        ! --> now reduce a * z = eig * b * z to the standard form a' * z' = eig * z'
     100             :        ! --> where a' = (l)^-1 * a * (l^t)^-1 and z' = l^t * z
     101           0 :        CALL zhegst(1,'U',smat%matsize1,hmat%data_c,SIZE(hmat%data_c,1),smat%data_c,SIZE(smat%data_c,1),info)
     102           0 :        IF (info.NE.0) THEN
     103           0 :           WRITE (oUnit,*) 'Error in zhegst: info =',info
     104           0 :           CALL juDFT_error("Diagonalization failed",calledby="chase_diag")
     105             :        ENDIF
     106             : 
     107             :        ! --> solve a' * z' = eig * z' for eigenvalues eig between lb und ub
     108           0 :        BLOCK
     109           0 :         COMPLEX(kind=sp),allocatable:: h(:,:),z(:,:),work(:)
     110           0 :         REAL(kind=sp),allocatable:: eigval(:),rwork(:)
     111           0 :         integer,allocatable      :: iwork(:),ifail(:)
     112           0 :         Allocate(h(size(hmat%data_c,1),size(hmat%data_c,2)))
     113           0 :         Allocate(eigval(size(hmat%data_c,1)),ifail(size(hmat%data_c,1)))
     114           0 :         Allocate(z(size(hmat%data_c,1),ne),rwork(7*size(hmat%data_c,1)))
     115           0 :         h=hmat%data_c
     116             : 
     117           0 :         allocate(work(1),iwork(5*size(hmat%data_c,1)))
     118           0 :         call cheevx('V','I','U',size(h,1),h,size(h,1),0.0,0.0,1,ne,0.0,nev,eigval,z,size(z,1),work,-1,rwork,iwork,ifail,info)
     119           0 :         lwork=work(1)
     120           0 :         deallocate(work)
     121           0 :         allocate(work(lwork))
     122             : 
     123           0 :         call cheevx('V','I','U',size(h,1),h,size(h,1),0.0,0.0,1,ne,0.0,nev,eigval,z,size(z,1),work,lwork,rwork,iwork,ifail,info)
     124           0 :         eig=eigval(:ne)
     125           0 :         zmat%data_c=z(:,:ne)
     126           0 :         deallocate(h,z,eigval,work,rwork,iwork)
     127             :         END BLOCK   
     128             : 
     129             :        ! --> recover the generalized eigenvectors z by solving z' = l^t * z
     130           0 :        CALL ztrtrs('U','N','N',hmat%matsize1,nev,smat%data_c,smat%matsize1,zMat%data_c,zmat%matsize1,info)
     131           0 :        IF (info.NE.0) THEN
     132           0 :           WRITE (oUnit,*) 'Error in ztrtrs: info =',info
     133           0 :           CALL juDFT_error("Diagonalization failed",calledby="chase_diag")
     134             :        ENDIF
     135             : 
     136             : 
     137             :     ENDIF
     138           0 :     IF (info.NE.0) CALL judft_error("Diagonalization via ChASE failed", calledby = 'chase_diag')
     139           0 :   END SUBROUTINE lapack_singlePREC_diag
     140             : 
     141             :   END MODULE m_lapack_singlePrec_diag

Generated by: LCOV version 1.14