LCOV - code coverage report
Current view: top level - src/common - eigenvalueproblems.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:4dc10b3) Lines: 12 49 24.5 %
Date: 2024-11-21 06:45:46 Functions: 1 4 25.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2024 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief Provides interfaces to LAPACK eigenvalue/SVD routines
      10             : !> \note
      11             : !>      We are using LAPACK interfaces, so please make sure in IBM/AIX you have
      12             : !>      the lapack library before essl: "xlf90 ... -llapack -lessl" !!!
      13             : !> \par History
      14             : !>      JGH (26-5-2001): delay D/S C/Z problem to the lapack library call
      15             : !> \author APSI
      16             : ! **************************************************************************************************
      17             : MODULE eigenvalueproblems
      18             : 
      19             :    USE kinds,                           ONLY: dp
      20             :    USE lapack,                          ONLY: lapack_cgesvd,&
      21             :                                               lapack_chpev,&
      22             :                                               lapack_sgesvd,&
      23             :                                               lapack_ssyev
      24             : #include "../base/base_uses.f90"
      25             : 
      26             :    IMPLICIT NONE
      27             : 
      28             :    PRIVATE
      29             : 
      30             :    PUBLIC :: diagonalise
      31             : 
      32             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'eigenvalueproblems'
      33             : 
      34             :    INTERFACE diagonalise
      35             :       MODULE PROCEDURE diagonalise_ssyev
      36             :       MODULE PROCEDURE diagonalise_chpev
      37             :    END INTERFACE
      38             : 
      39             :    INTERFACE singular_values
      40             :       MODULE PROCEDURE cp2k_sgesvd
      41             :       MODULE PROCEDURE cp2k_cgesvd
      42             :    END INTERFACE
      43             : 
      44             : CONTAINS
      45             : 
      46             : ! **************************************************************************************************
      47             : !> \brief ...
      48             : !> \param matrix ...
      49             : !> \param mysize ...
      50             : !> \param storageform ...
      51             : !> \param eigenvalues ...
      52             : !> \param eigenvectors ...
      53             : ! **************************************************************************************************
      54         988 :    SUBROUTINE diagonalise_ssyev(matrix, mysize, storageform, eigenvalues, &
      55         988 :                                 eigenvectors)
      56             : 
      57             :       REAL(KIND=dp), INTENT(IN)                          :: matrix(:, :)
      58             :       INTEGER, INTENT(IN)                                :: mysize
      59             :       CHARACTER(LEN=*), INTENT(IN)                       :: storageform
      60             :       REAL(KIND=dp), INTENT(OUT)                         :: eigenvalues(:), eigenvectors(:, :)
      61             : 
      62             :       CHARACTER, PARAMETER                               :: jobz = "V"
      63             : 
      64             :       CHARACTER                                          :: uplo
      65             :       INTEGER                                            :: info, lda, lwork
      66        1976 :       REAL(KIND=dp)                                      :: work(3*mysize - 1)
      67             : 
      68             :       IF (storageform(1:5) == "Lower" .OR. &
      69         988 :           storageform(1:5) == "LOWER" .OR. &
      70             :           storageform(1:5) == "lower") THEN
      71           0 :          uplo = "L"
      72             :       ELSE IF (storageform(1:5) == "Upper" .OR. &
      73         988 :                storageform(1:5) == "upper" .OR. &
      74             :                storageform(1:5) == "UPPER") THEN
      75         988 :          uplo = "U"
      76             :       ELSE
      77           0 :          CPABORT("Unknown form of storage")
      78             :       END IF
      79             : 
      80         988 :       lda = SIZE(matrix, 1)
      81         988 :       lwork = 3*mysize - 1
      82             : 
      83       12844 :       eigenvectors = matrix
      84             : 
      85             :       CALL lapack_ssyev(jobz, uplo, mysize, eigenvectors, lda, eigenvalues, &
      86         988 :                         work, lwork, info)
      87         988 :       IF (info /= 0) THEN
      88           0 :          CPABORT("Error in diagonalisation")
      89             :       END IF
      90             : 
      91         988 :    END SUBROUTINE diagonalise_ssyev
      92             : 
      93             : ! **************************************************************************************************
      94             : !> \brief ...
      95             : !> \param matrix ...
      96             : !> \param mysize ...
      97             : !> \param storageform ...
      98             : !> \param eigenvalues ...
      99             : !> \param eigenvectors ...
     100             : ! **************************************************************************************************
     101           0 :    SUBROUTINE diagonalise_chpev(matrix, mysize, storageform, eigenvalues, &
     102           0 :                                 eigenvectors)
     103             : 
     104             :       COMPLEX(KIND=dp), INTENT(INOUT)                    :: matrix(:)
     105             :       INTEGER, INTENT(IN)                                :: mysize
     106             :       CHARACTER(LEN=*), INTENT(IN)                       :: storageform
     107             :       REAL(KIND=dp), INTENT(OUT)                         :: eigenvalues(:)
     108             :       COMPLEX(KIND=dp), INTENT(OUT)                      :: eigenvectors(:, :)
     109             : 
     110             :       CHARACTER, PARAMETER                               :: jobz = "V"
     111             : 
     112             :       CHARACTER                                          :: uplo
     113             :       INTEGER                                            :: info
     114           0 :       COMPLEX(KIND=dp)                                   :: work(2*mysize - 1)
     115           0 :       REAL(KIND=dp)                                      :: rwork(3*mysize - 2)
     116             : 
     117             :       IF (storageform(1:5) == "Lower" .OR. &
     118           0 :           storageform(1:5) == "LOWER" .OR. &
     119             :           storageform(1:5) == "lower") THEN
     120           0 :          uplo = "L"
     121             :       ELSE IF (storageform(1:5) == "Upper" .OR. &
     122           0 :                storageform(1:5) == "upper" .OR. &
     123             :                storageform(1:5) == "UPPER") THEN
     124           0 :          uplo = "U"
     125             :       ELSE
     126           0 :          CPABORT("Unknown form of storage")
     127             :       END IF
     128             : 
     129             :       CALL lapack_chpev(jobz, uplo, mysize, matrix, eigenvalues, &
     130           0 :                         eigenvectors, mysize, work, rwork, info)
     131           0 :       IF (info /= 0) THEN
     132           0 :          CPABORT("Error in diagonalisation")
     133             :       END IF
     134             : 
     135           0 :    END SUBROUTINE diagonalise_chpev
     136             : 
     137             : ! **************************************************************************************************
     138             : !> \brief ...
     139             : !> \param matrix ...
     140             : !> \param svalues ...
     141             : !> \param mrow ...
     142             : !> \param ncol ...
     143             : !> \param uvec ...
     144             : !> \param vtvec ...
     145             : ! **************************************************************************************************
     146           0 :    SUBROUTINE cp2k_sgesvd(matrix, svalues, mrow, ncol, uvec, vtvec)
     147             : 
     148             :       REAL(KIND=dp), INTENT(IN)                          :: matrix(:, :)
     149             :       REAL(KIND=dp), INTENT(OUT)                         :: svalues(:)
     150             :       INTEGER, INTENT(IN)                                :: mrow, ncol
     151             :       REAL(KIND=dp), INTENT(OUT)                         :: uvec(:, :), vtvec(:, :)
     152             : 
     153             :       CHARACTER, PARAMETER                               :: jobu = "A", jobvt = "A"
     154             : 
     155             :       INTEGER                                            :: info, lda, ldu, ldvt, lwork
     156           0 :       REAL(KIND=dp)                                      :: work(25*(mrow + ncol))
     157             : 
     158           0 :       lwork = 25*(mrow + ncol)
     159           0 :       lda = SIZE(matrix, 1)
     160           0 :       ldu = SIZE(uvec, 1)
     161           0 :       ldvt = SIZE(vtvec, 1)
     162             : 
     163             :       CALL lapack_sgesvd(jobu, jobvt, mrow, ncol, matrix, lda, svalues, &
     164           0 :                          uvec, ldu, vtvec, ldvt, work, lwork, info)
     165           0 :       IF (info /= 0) THEN
     166           0 :          CPABORT("Error in singular value decomposition.")
     167             :       END IF
     168             : 
     169           0 :    END SUBROUTINE cp2k_sgesvd
     170             : 
     171             : ! **************************************************************************************************
     172             : !> \brief ...
     173             : !> \param matrix ...
     174             : !> \param svalues ...
     175             : !> \param mrow ...
     176             : !> \param ncol ...
     177             : !> \param uvec ...
     178             : !> \param vtvec ...
     179             : ! **************************************************************************************************
     180           0 :    SUBROUTINE cp2k_cgesvd(matrix, svalues, mrow, ncol, uvec, vtvec)
     181             : 
     182             :       COMPLEX(KIND=dp), INTENT(IN)                       :: matrix(:, :)
     183             :       REAL(KIND=dp), INTENT(OUT)                         :: svalues(:)
     184             :       INTEGER, INTENT(IN)                                :: mrow, ncol
     185             :       COMPLEX(KIND=dp), INTENT(OUT)                      :: uvec(:, :), vtvec(:, :)
     186             : 
     187             :       CHARACTER, PARAMETER                               :: jobu = "A", jobvt = "A"
     188             : 
     189             :       INTEGER                                            :: info, lda, ldu, ldvt, lwork
     190           0 :       COMPLEX(KIND=dp)                                   :: work(25*(mrow + ncol))
     191           0 :       REAL(KIND=dp)                                      :: rwork(25*(mrow + ncol))
     192             : 
     193           0 :       lwork = 25*(mrow + ncol)
     194           0 :       lda = SIZE(matrix, 1)
     195           0 :       ldu = SIZE(uvec, 1)
     196           0 :       ldvt = SIZE(vtvec, 1)
     197             : 
     198             :       CALL lapack_cgesvd(jobu, jobvt, mrow, ncol, matrix, lda, svalues, &
     199           0 :                          uvec, ldu, vtvec, ldvt, work, lwork, rwork, info)
     200           0 :       IF (info /= 0) THEN
     201           0 :          CPABORT("Error in singular value decomposition.")
     202             :       END IF
     203             : 
     204           0 :    END SUBROUTINE cp2k_cgesvd
     205             : 
     206             : END MODULE eigenvalueproblems
     207             : 

Generated by: LCOV version 1.15