LCOV - code coverage report
Current view: top level - src - almo_scf_diis_types.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:2fce0f8) Lines: 167 189 88.4 %
Date: 2024-12-21 06:28:57 Functions: 6 8 75.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 A DIIS implementation for the ALMO-based SCF methods
      10             : !> \par History
      11             : !>       2011.12 created [Rustam Z Khaliullin]
      12             : !> \author Rustam Z Khaliullin
      13             : ! **************************************************************************************************
      14             : MODULE almo_scf_diis_types
      15             :    USE cp_dbcsr_api,                    ONLY: dbcsr_add,&
      16             :                                               dbcsr_copy,&
      17             :                                               dbcsr_create,&
      18             :                                               dbcsr_dot,&
      19             :                                               dbcsr_release,&
      20             :                                               dbcsr_set,&
      21             :                                               dbcsr_type
      22             :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      23             :                                               cp_logger_get_default_unit_nr,&
      24             :                                               cp_logger_type
      25             :    USE domain_submatrix_methods,        ONLY: add_submatrices,&
      26             :                                               copy_submatrices,&
      27             :                                               init_submatrices,&
      28             :                                               release_submatrices,&
      29             :                                               set_submatrices
      30             :    USE domain_submatrix_types,          ONLY: domain_submatrix_type
      31             :    USE kinds,                           ONLY: dp
      32             : #include "./base/base_uses.f90"
      33             : 
      34             :    IMPLICIT NONE
      35             : 
      36             :    PRIVATE
      37             : 
      38             :    INTEGER, PARAMETER :: diis_error_orthogonal = 1
      39             : 
      40             :    INTEGER, PARAMETER :: diis_env_dbcsr = 1
      41             :    INTEGER, PARAMETER :: diis_env_domain = 2
      42             : 
      43             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'almo_scf_diis_types'
      44             : 
      45             :    PUBLIC :: almo_scf_diis_type, &
      46             :              almo_scf_diis_init, almo_scf_diis_release, almo_scf_diis_push, &
      47             :              almo_scf_diis_extrapolate
      48             : 
      49             :    INTERFACE almo_scf_diis_init
      50             :       MODULE PROCEDURE almo_scf_diis_init_dbcsr
      51             :       MODULE PROCEDURE almo_scf_diis_init_domain
      52             :    END INTERFACE
      53             : 
      54             :    TYPE almo_scf_diis_type
      55             : 
      56             :       INTEGER :: diis_env_type = 0
      57             : 
      58             :       INTEGER :: buffer_length = 0
      59             :       INTEGER :: max_buffer_length = 0
      60             :       !INTEGER, DIMENSION(:), ALLOCATABLE :: history_index
      61             : 
      62             :       TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: m_var
      63             :       TYPE(dbcsr_type), DIMENSION(:), ALLOCATABLE :: m_err
      64             : 
      65             :       ! first dimension is history index, second - domain index
      66             :       TYPE(domain_submatrix_type), DIMENSION(:, :), ALLOCATABLE :: d_var
      67             :       TYPE(domain_submatrix_type), DIMENSION(:, :), ALLOCATABLE :: d_err
      68             : 
      69             :       ! distributed matrix of error overlaps
      70             :       TYPE(domain_submatrix_type), DIMENSION(:), ALLOCATABLE     :: m_b
      71             : 
      72             :       ! insertion point
      73             :       INTEGER :: in_point = 0
      74             : 
      75             :       ! in order to calculate the overlap between error vectors
      76             :       ! it is desirable to know tensorial properties of the error
      77             :       ! vector, e.g. convariant, contravariant, orthogonal
      78             :       INTEGER :: error_type = 0
      79             : 
      80             :    END TYPE almo_scf_diis_type
      81             : 
      82             : CONTAINS
      83             : 
      84             : ! **************************************************************************************************
      85             : !> \brief initializes the diis structure
      86             : !> \param diis_env ...
      87             : !> \param sample_err ...
      88             : !> \param sample_var ...
      89             : !> \param error_type ...
      90             : !> \param max_length ...
      91             : !> \par History
      92             : !>       2011.12 created [Rustam Z Khaliullin]
      93             : !> \author Rustam Z Khaliullin
      94             : ! **************************************************************************************************
      95          76 :    SUBROUTINE almo_scf_diis_init_dbcsr(diis_env, sample_err, sample_var, error_type, &
      96             :                                        max_length)
      97             : 
      98             :       TYPE(almo_scf_diis_type), INTENT(INOUT)            :: diis_env
      99             :       TYPE(dbcsr_type), INTENT(IN)                       :: sample_err, sample_var
     100             :       INTEGER, INTENT(IN)                                :: error_type, max_length
     101             : 
     102             :       CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_diis_init_dbcsr'
     103             : 
     104             :       INTEGER                                            :: handle, idomain, im, ndomains
     105             : 
     106          76 :       CALL timeset(routineN, handle)
     107             : 
     108          76 :       IF (max_length .LE. 0) THEN
     109           0 :          CPABORT("DIIS: max_length is less than zero")
     110             :       END IF
     111             : 
     112          76 :       diis_env%diis_env_type = diis_env_dbcsr
     113             : 
     114          76 :       diis_env%max_buffer_length = max_length
     115          76 :       diis_env%buffer_length = 0
     116          76 :       diis_env%error_type = error_type
     117          76 :       diis_env%in_point = 1
     118             : 
     119         600 :       ALLOCATE (diis_env%m_err(diis_env%max_buffer_length))
     120         600 :       ALLOCATE (diis_env%m_var(diis_env%max_buffer_length))
     121             : 
     122             :       ! create matrices
     123         448 :       DO im = 1, diis_env%max_buffer_length
     124             :          CALL dbcsr_create(diis_env%m_err(im), &
     125         372 :                            template=sample_err)
     126             :          CALL dbcsr_create(diis_env%m_var(im), &
     127         448 :                            template=sample_var)
     128             :       END DO
     129             : 
     130             :       ! current B matrices are only 1-by-1, they will be expanded on-the-fly
     131             :       ! only one matrix is used with dbcsr version of DIIS
     132          76 :       ndomains = 1
     133         152 :       ALLOCATE (diis_env%m_b(ndomains))
     134          76 :       CALL init_submatrices(diis_env%m_b)
     135             :       ! hack into d_b structure to gain full control
     136         152 :       diis_env%m_b(:)%domain = 100 ! arbitrary positive number
     137         152 :       DO idomain = 1, ndomains
     138         152 :          IF (diis_env%m_b(idomain)%domain .GT. 0) THEN
     139          76 :             ALLOCATE (diis_env%m_b(idomain)%mdata(1, 1))
     140         228 :             diis_env%m_b(idomain)%mdata(:, :) = 0.0_dp
     141             :          END IF
     142             :       END DO
     143             : 
     144          76 :       CALL timestop(handle)
     145             : 
     146          76 :    END SUBROUTINE almo_scf_diis_init_dbcsr
     147             : 
     148             : ! **************************************************************************************************
     149             : !> \brief initializes the diis structure
     150             : !> \param diis_env ...
     151             : !> \param sample_err ...
     152             : !> \param error_type ...
     153             : !> \param max_length ...
     154             : !> \par History
     155             : !>       2011.12 created [Rustam Z Khaliullin]
     156             : !> \author Rustam Z Khaliullin
     157             : ! **************************************************************************************************
     158           2 :    SUBROUTINE almo_scf_diis_init_domain(diis_env, sample_err, error_type, &
     159             :                                         max_length)
     160             : 
     161             :       TYPE(almo_scf_diis_type), INTENT(INOUT)            :: diis_env
     162             :       TYPE(domain_submatrix_type), DIMENSION(:), &
     163             :          INTENT(IN)                                      :: sample_err
     164             :       INTEGER, INTENT(IN)                                :: error_type, max_length
     165             : 
     166             :       CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_diis_init_domain'
     167             : 
     168             :       INTEGER                                            :: handle, idomain, ndomains
     169             : 
     170           2 :       CALL timeset(routineN, handle)
     171             : 
     172           2 :       IF (max_length .LE. 0) THEN
     173           0 :          CPABORT("DIIS: max_length is less than zero")
     174             :       END IF
     175             : 
     176           2 :       diis_env%diis_env_type = diis_env_domain
     177             : 
     178           2 :       diis_env%max_buffer_length = max_length
     179           2 :       diis_env%buffer_length = 0
     180           2 :       diis_env%error_type = error_type
     181           2 :       diis_env%in_point = 1
     182             : 
     183           2 :       ndomains = SIZE(sample_err)
     184             : 
     185          38 :       ALLOCATE (diis_env%d_err(diis_env%max_buffer_length, ndomains))
     186          38 :       ALLOCATE (diis_env%d_var(diis_env%max_buffer_length, ndomains))
     187             : 
     188             :       ! create matrices
     189           2 :       CALL init_submatrices(diis_env%d_var)
     190           2 :       CALL init_submatrices(diis_env%d_err)
     191             : 
     192             :       ! current B matrices are only 1-by-1, they will be expanded on-the-fly
     193          16 :       ALLOCATE (diis_env%m_b(ndomains))
     194           2 :       CALL init_submatrices(diis_env%m_b)
     195             :       ! hack into d_b structure to gain full control
     196             :       ! distribute matrices as the err/var matrices
     197          12 :       diis_env%m_b(:)%domain = sample_err(:)%domain
     198          12 :       DO idomain = 1, ndomains
     199          12 :          IF (diis_env%m_b(idomain)%domain .GT. 0) THEN
     200           5 :             ALLOCATE (diis_env%m_b(idomain)%mdata(1, 1))
     201          15 :             diis_env%m_b(idomain)%mdata(:, :) = 0.0_dp
     202             :          END IF
     203             :       END DO
     204             : 
     205           2 :       CALL timestop(handle)
     206             : 
     207           2 :    END SUBROUTINE almo_scf_diis_init_domain
     208             : 
     209             : ! **************************************************************************************************
     210             : !> \brief adds a variable-error pair to the diis structure
     211             : !> \param diis_env ...
     212             : !> \param var ...
     213             : !> \param err ...
     214             : !> \param d_var ...
     215             : !> \param d_err ...
     216             : !> \par History
     217             : !>       2011.12 created [Rustam Z Khaliullin]
     218             : !> \author Rustam Z Khaliullin
     219             : ! **************************************************************************************************
     220         426 :    SUBROUTINE almo_scf_diis_push(diis_env, var, err, d_var, d_err)
     221             :       TYPE(almo_scf_diis_type), INTENT(INOUT)            :: diis_env
     222             :       TYPE(dbcsr_type), INTENT(IN), OPTIONAL             :: var, err
     223             :       TYPE(domain_submatrix_type), DIMENSION(:), &
     224             :          INTENT(IN), OPTIONAL                            :: d_var, d_err
     225             : 
     226             :       CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_diis_push'
     227             : 
     228             :       INTEGER                                            :: handle, idomain, in_point, irow, &
     229             :                                                             ndomains, old_buffer_length
     230             :       REAL(KIND=dp)                                      :: trace0
     231         426 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: m_b_tmp
     232             : 
     233         426 :       CALL timeset(routineN, handle)
     234             : 
     235         426 :       IF (diis_env%diis_env_type .EQ. diis_env_dbcsr) THEN
     236         424 :          IF (.NOT. (PRESENT(var) .AND. PRESENT(err))) THEN
     237           0 :             CPABORT("provide DBCSR matrices")
     238             :          END IF
     239           2 :       ELSE IF (diis_env%diis_env_type .EQ. diis_env_domain) THEN
     240           2 :          IF (.NOT. (PRESENT(d_var) .AND. PRESENT(d_err))) THEN
     241           0 :             CPABORT("provide domain submatrices")
     242             :          END IF
     243             :       ELSE
     244           0 :          CPABORT("illegal DIIS ENV type")
     245             :       END IF
     246             : 
     247         426 :       in_point = diis_env%in_point
     248             : 
     249             :       ! store a var-error pair
     250         426 :       IF (diis_env%diis_env_type .EQ. diis_env_dbcsr) THEN
     251         424 :          CALL dbcsr_copy(diis_env%m_var(in_point), var)
     252         424 :          CALL dbcsr_copy(diis_env%m_err(in_point), err)
     253           2 :       ELSE IF (diis_env%diis_env_type .EQ. diis_env_domain) THEN
     254           2 :          CALL copy_submatrices(d_var, diis_env%d_var(in_point, :), copy_data=.TRUE.)
     255           2 :          CALL copy_submatrices(d_err, diis_env%d_err(in_point, :), copy_data=.TRUE.)
     256             :       END IF
     257             : 
     258             :       ! update the buffer length
     259         426 :       old_buffer_length = diis_env%buffer_length
     260         426 :       diis_env%buffer_length = diis_env%buffer_length + 1
     261         426 :       IF (diis_env%buffer_length .GT. diis_env%max_buffer_length) &
     262          96 :          diis_env%buffer_length = diis_env%max_buffer_length
     263             : 
     264             :       !!!! resize B matrix
     265             :       !!!IF (old_buffer_length.lt.diis_env%buffer_length) THEN
     266             :       !!!   ALLOCATE(m_b_tmp(diis_env%buffer_length+1,diis_env%buffer_length+1))
     267             :       !!!   m_b_tmp(1:diis_env%buffer_length,1:diis_env%buffer_length)=&
     268             :       !!!      diis_env%m_b(:,:)
     269             :       !!!   DEALLOCATE(diis_env%m_b)
     270             :       !!!   ALLOCATE(diis_env%m_b(diis_env%buffer_length+1,&
     271             :       !!!      diis_env%buffer_length+1))
     272             :       !!!   diis_env%m_b(:,:)=m_b_tmp(:,:)
     273             :       !!!   DEALLOCATE(m_b_tmp)
     274             :       !!!ENDIF
     275             :       !!!! update B matrix elements
     276             :       !!!diis_env%m_b(1,in_point+1)=-1.0_dp
     277             :       !!!diis_env%m_b(in_point+1,1)=-1.0_dp
     278             :       !!!DO irow=1,diis_env%buffer_length
     279             :       !!!   trace0=almo_scf_diis_error_overlap(diis_env,&
     280             :       !!!      A=diis_env%m_err(irow),B=diis_env%m_err(in_point))
     281             :       !!!
     282             :       !!!   diis_env%m_b(irow+1,in_point+1)=trace0
     283             :       !!!   diis_env%m_b(in_point+1,irow+1)=trace0
     284             :       !!!ENDDO
     285             : 
     286             :       ! resize B matrix and update its elements
     287         426 :       ndomains = SIZE(diis_env%m_b)
     288         426 :       IF (old_buffer_length .LT. diis_env%buffer_length) THEN
     289        1320 :          ALLOCATE (m_b_tmp(diis_env%buffer_length + 1, diis_env%buffer_length + 1))
     290         668 :          DO idomain = 1, ndomains
     291         668 :             IF (diis_env%m_b(idomain)%domain .GT. 0) THEN
     292        6947 :                m_b_tmp(:, :) = 0.0_dp
     293             :                m_b_tmp(1:diis_env%buffer_length, 1:diis_env%buffer_length) = &
     294        4447 :                   diis_env%m_b(idomain)%mdata(:, :)
     295         333 :                DEALLOCATE (diis_env%m_b(idomain)%mdata)
     296           0 :                ALLOCATE (diis_env%m_b(idomain)%mdata(diis_env%buffer_length + 1, &
     297        1332 :                                                      diis_env%buffer_length + 1))
     298        6947 :                diis_env%m_b(idomain)%mdata(:, :) = m_b_tmp(:, :)
     299             :             END IF
     300             :          END DO
     301         330 :          DEALLOCATE (m_b_tmp)
     302             :       END IF
     303         860 :       DO idomain = 1, ndomains
     304         860 :          IF (diis_env%m_b(idomain)%domain .GT. 0) THEN
     305         429 :             diis_env%m_b(idomain)%mdata(1, in_point + 1) = -1.0_dp
     306         429 :             diis_env%m_b(idomain)%mdata(in_point + 1, 1) = -1.0_dp
     307        1796 :             DO irow = 1, diis_env%buffer_length
     308        1367 :                IF (diis_env%diis_env_type .EQ. diis_env_dbcsr) THEN
     309             :                   trace0 = almo_scf_diis_error_overlap(diis_env, &
     310        1362 :                                                        A=diis_env%m_err(irow), B=diis_env%m_err(in_point))
     311           5 :                ELSE IF (diis_env%diis_env_type .EQ. diis_env_domain) THEN
     312             :                   trace0 = almo_scf_diis_error_overlap(diis_env, &
     313             :                                                        d_A=diis_env%d_err(irow, idomain), &
     314           5 :                                                        d_B=diis_env%d_err(in_point, idomain))
     315             :                END IF
     316        1367 :                diis_env%m_b(idomain)%mdata(irow + 1, in_point + 1) = trace0
     317        1796 :                diis_env%m_b(idomain)%mdata(in_point + 1, irow + 1) = trace0
     318             :             END DO ! loop over prev errors
     319             :          END IF
     320             :       END DO ! loop over domains
     321             : 
     322             :       ! update the insertion point for the next "PUSH"
     323         426 :       diis_env%in_point = diis_env%in_point + 1
     324         426 :       IF (diis_env%in_point .GT. diis_env%max_buffer_length) diis_env%in_point = 1
     325             : 
     326         426 :       CALL timestop(handle)
     327             : 
     328         426 :    END SUBROUTINE almo_scf_diis_push
     329             : 
     330             : ! **************************************************************************************************
     331             : !> \brief extrapolates the variable using the saved history
     332             : !> \param diis_env ...
     333             : !> \param extr_var ...
     334             : !> \param d_extr_var ...
     335             : !> \par History
     336             : !>       2011.12 created [Rustam Z Khaliullin]
     337             : !> \author Rustam Z Khaliullin
     338             : ! **************************************************************************************************
     339         272 :    SUBROUTINE almo_scf_diis_extrapolate(diis_env, extr_var, d_extr_var)
     340             :       TYPE(almo_scf_diis_type), INTENT(INOUT)            :: diis_env
     341             :       TYPE(dbcsr_type), INTENT(INOUT), OPTIONAL          :: extr_var
     342             :       TYPE(domain_submatrix_type), DIMENSION(:), &
     343             :          INTENT(INOUT), OPTIONAL                         :: d_extr_var
     344             : 
     345             :       CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_diis_extrapolate'
     346             : 
     347             :       INTEGER                                            :: handle, idomain, im, INFO, LWORK, &
     348             :                                                             ndomains, unit_nr
     349             :       REAL(KIND=dp)                                      :: checksum
     350         272 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: coeff, eigenvalues, tmp1, WORK
     351         272 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :)        :: m_b_copy
     352             :       TYPE(cp_logger_type), POINTER                      :: logger
     353             : 
     354         272 :       CALL timeset(routineN, handle)
     355             : 
     356             :       ! get a useful output_unit
     357         272 :       logger => cp_get_default_logger()
     358         272 :       IF (logger%para_env%is_source()) THEN
     359         136 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
     360             :       ELSE
     361             :          unit_nr = -1
     362             :       END IF
     363             : 
     364         272 :       IF (diis_env%diis_env_type .EQ. diis_env_dbcsr) THEN
     365         272 :          IF (.NOT. PRESENT(extr_var)) THEN
     366           0 :             CPABORT("provide DBCSR matrix")
     367             :          END IF
     368           0 :       ELSE IF (diis_env%diis_env_type .EQ. diis_env_domain) THEN
     369           0 :          IF (.NOT. PRESENT(d_extr_var)) THEN
     370           0 :             CPABORT("provide domain submatrices")
     371             :          END IF
     372             :       ELSE
     373           0 :          CPABORT("illegal DIIS ENV type")
     374             :       END IF
     375             : 
     376             :       ! Prepare data
     377         816 :       ALLOCATE (eigenvalues(diis_env%buffer_length + 1))
     378        1088 :       ALLOCATE (m_b_copy(diis_env%buffer_length + 1, diis_env%buffer_length + 1))
     379             : 
     380         272 :       ndomains = SIZE(diis_env%m_b)
     381             : 
     382         544 :       DO idomain = 1, ndomains
     383             : 
     384         544 :          IF (diis_env%m_b(idomain)%domain .GT. 0) THEN
     385             : 
     386        7456 :             m_b_copy(:, :) = diis_env%m_b(idomain)%mdata(:, :)
     387             : 
     388             :             ! Query the optimal workspace for dsyev
     389         272 :             LWORK = -1
     390         272 :             ALLOCATE (WORK(MAX(1, LWORK)))
     391             :             CALL DSYEV('V', 'L', diis_env%buffer_length + 1, m_b_copy, &
     392         272 :                        diis_env%buffer_length + 1, eigenvalues, WORK, LWORK, INFO)
     393         272 :             LWORK = INT(WORK(1))
     394         272 :             DEALLOCATE (WORK)
     395             : 
     396             :             ! Allocate the workspace and solve the eigenproblem
     397         816 :             ALLOCATE (WORK(MAX(1, LWORK)))
     398             :             CALL DSYEV('V', 'L', diis_env%buffer_length + 1, m_b_copy, &
     399         272 :                        diis_env%buffer_length + 1, eigenvalues, WORK, LWORK, INFO)
     400         272 :             IF (INFO .NE. 0) THEN
     401           0 :                CPABORT("DSYEV failed")
     402             :             END IF
     403         272 :             DEALLOCATE (WORK)
     404             : 
     405             :             ! use the eigensystem to invert (implicitly) B matrix
     406             :             ! and compute the extrapolation coefficients
     407             :             !! ALLOCATE(tmp1(diis_env%buffer_length+1,1))
     408             :             !! ALLOCATE(coeff(diis_env%buffer_length+1,1))
     409             :             !! tmp1(:,1)=-1.0_dp*m_b_copy(1,:)/eigenvalues(:)
     410             :             !! coeff=MATMUL(m_b_copy,tmp1)
     411             :             !! DEALLOCATE(tmp1)
     412         816 :             ALLOCATE (tmp1(diis_env%buffer_length + 1))
     413         544 :             ALLOCATE (coeff(diis_env%buffer_length + 1))
     414        1502 :             tmp1(:) = -1.0_dp*m_b_copy(1, :)/eigenvalues(:)
     415        8686 :             coeff(:) = MATMUL(m_b_copy, tmp1)
     416         272 :             DEALLOCATE (tmp1)
     417             : 
     418             :             !IF (unit_nr.gt.0) THEN
     419             :             !   DO im=1,diis_env%buffer_length+1
     420             :             !      WRITE(unit_nr,*) diis_env%m_b(idomain)%mdata(im,:)
     421             :             !   ENDDO
     422             :             !   WRITE (unit_nr,*) coeff(:,1)
     423             :             !ENDIF
     424             : 
     425             :             ! extrapolate the variable
     426         272 :             checksum = 0.0_dp
     427         272 :             IF (diis_env%diis_env_type .EQ. diis_env_dbcsr) THEN
     428         272 :                CALL dbcsr_set(extr_var, 0.0_dp)
     429        1230 :                DO im = 1, diis_env%buffer_length
     430             :                   CALL dbcsr_add(extr_var, diis_env%m_var(im), &
     431         958 :                                  1.0_dp, coeff(im + 1))
     432        1230 :                   checksum = checksum + coeff(im + 1)
     433             :                END DO
     434           0 :             ELSE IF (diis_env%diis_env_type .EQ. diis_env_domain) THEN
     435             :                CALL copy_submatrices(diis_env%d_var(1, idomain), &
     436             :                                      d_extr_var(idomain), &
     437           0 :                                      copy_data=.FALSE.)
     438           0 :                CALL set_submatrices(d_extr_var(idomain), 0.0_dp)
     439           0 :                DO im = 1, diis_env%buffer_length
     440             :                   CALL add_submatrices(1.0_dp, d_extr_var(idomain), &
     441             :                                        coeff(im + 1), diis_env%d_var(im, idomain), &
     442           0 :                                        'N')
     443           0 :                   checksum = checksum + coeff(im + 1)
     444             :                END DO
     445             :             END IF
     446             :             !WRITE(*,*) checksum
     447             : 
     448         272 :             DEALLOCATE (coeff)
     449             : 
     450             :          END IF ! domain is local to this mpi node
     451             : 
     452             :       END DO ! loop over domains
     453             : 
     454         272 :       DEALLOCATE (eigenvalues)
     455         272 :       DEALLOCATE (m_b_copy)
     456             : 
     457         272 :       CALL timestop(handle)
     458             : 
     459         544 :    END SUBROUTINE almo_scf_diis_extrapolate
     460             : 
     461             : ! **************************************************************************************************
     462             : !> \brief computes elements of b-matrix
     463             : !> \param diis_env ...
     464             : !> \param A ...
     465             : !> \param B ...
     466             : !> \param d_A ...
     467             : !> \param d_B ...
     468             : !> \return ...
     469             : !> \par History
     470             : !>       2013.02 created [Rustam Z Khaliullin]
     471             : !> \author Rustam Z Khaliullin
     472             : ! **************************************************************************************************
     473        1367 :    FUNCTION almo_scf_diis_error_overlap(diis_env, A, B, d_A, d_B)
     474             : 
     475             :       TYPE(almo_scf_diis_type), INTENT(INOUT)            :: diis_env
     476             :       TYPE(dbcsr_type), INTENT(INOUT), OPTIONAL          :: A, B
     477             :       TYPE(domain_submatrix_type), INTENT(INOUT), &
     478             :          OPTIONAL                                        :: d_A, d_B
     479             :       REAL(KIND=dp)                                      :: almo_scf_diis_error_overlap
     480             : 
     481             :       CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_diis_error_overlap'
     482             : 
     483             :       INTEGER                                            :: handle
     484             :       REAL(KIND=dp)                                      :: trace
     485             : 
     486        1367 :       CALL timeset(routineN, handle)
     487             : 
     488        1367 :       IF (diis_env%diis_env_type .EQ. diis_env_dbcsr) THEN
     489        1362 :          IF (.NOT. (PRESENT(A) .AND. PRESENT(B))) THEN
     490           0 :             CPABORT("provide DBCSR matrices")
     491             :          END IF
     492           5 :       ELSE IF (diis_env%diis_env_type .EQ. diis_env_domain) THEN
     493           5 :          IF (.NOT. (PRESENT(d_A) .AND. PRESENT(d_B))) THEN
     494           0 :             CPABORT("provide domain submatrices")
     495             :          END IF
     496             :       ELSE
     497           0 :          CPABORT("illegal DIIS ENV type")
     498             :       END IF
     499             : 
     500        2734 :       SELECT CASE (diis_env%error_type)
     501             :       CASE (diis_error_orthogonal)
     502        1367 :          IF (diis_env%diis_env_type .EQ. diis_env_dbcsr) THEN
     503        1362 :             CALL dbcsr_dot(A, B, trace)
     504           5 :          ELSE IF (diis_env%diis_env_type .EQ. diis_env_domain) THEN
     505           5 :             CPASSERT(SIZE(d_A%mdata, 1) .EQ. SIZE(d_B%mdata, 1))
     506           5 :             CPASSERT(SIZE(d_A%mdata, 2) .EQ. SIZE(d_B%mdata, 2))
     507           5 :             CPASSERT(d_A%domain .EQ. d_B%domain)
     508           5 :             CPASSERT(d_A%domain .GT. 0)
     509           5 :             CPASSERT(d_B%domain .GT. 0)
     510       31607 :             trace = SUM(d_A%mdata(:, :)*d_B%mdata(:, :))
     511             :          END IF
     512             :       CASE DEFAULT
     513        1367 :          CPABORT("Vector type is unknown")
     514             :       END SELECT
     515             : 
     516        1367 :       almo_scf_diis_error_overlap = trace
     517             : 
     518        1367 :       CALL timestop(handle)
     519             : 
     520        1367 :    END FUNCTION almo_scf_diis_error_overlap
     521             : 
     522             : ! **************************************************************************************************
     523             : !> \brief destroys the diis structure
     524             : !> \param diis_env ...
     525             : !> \par History
     526             : !>       2011.12 created [Rustam Z Khaliullin]
     527             : !> \author Rustam Z Khaliullin
     528             : ! **************************************************************************************************
     529          78 :    SUBROUTINE almo_scf_diis_release(diis_env)
     530             :       TYPE(almo_scf_diis_type), INTENT(INOUT)            :: diis_env
     531             : 
     532             :       CHARACTER(len=*), PARAMETER :: routineN = 'almo_scf_diis_release'
     533             : 
     534             :       INTEGER                                            :: handle, im
     535             : 
     536          78 :       CALL timeset(routineN, handle)
     537             : 
     538             :       ! release matrices
     539         454 :       DO im = 1, diis_env%max_buffer_length
     540         454 :          IF (diis_env%diis_env_type .EQ. diis_env_dbcsr) THEN
     541         372 :             CALL dbcsr_release(diis_env%m_err(im))
     542         372 :             CALL dbcsr_release(diis_env%m_var(im))
     543           4 :          ELSE IF (diis_env%diis_env_type .EQ. diis_env_domain) THEN
     544           4 :             CALL release_submatrices(diis_env%d_var(im, :))
     545           4 :             CALL release_submatrices(diis_env%d_err(im, :))
     546             :          END IF
     547             :       END DO
     548             : 
     549          78 :       IF (diis_env%diis_env_type .EQ. diis_env_domain) THEN
     550           2 :          CALL release_submatrices(diis_env%m_b(:))
     551             :       END IF
     552             : 
     553         164 :       IF (ALLOCATED(diis_env%m_b)) DEALLOCATE (diis_env%m_b)
     554          78 :       IF (ALLOCATED(diis_env%m_err)) DEALLOCATE (diis_env%m_err)
     555          78 :       IF (ALLOCATED(diis_env%m_var)) DEALLOCATE (diis_env%m_var)
     556          98 :       IF (ALLOCATED(diis_env%d_err)) DEALLOCATE (diis_env%d_err)
     557          98 :       IF (ALLOCATED(diis_env%d_var)) DEALLOCATE (diis_env%d_var)
     558             : 
     559          78 :       CALL timestop(handle)
     560             : 
     561          78 :    END SUBROUTINE almo_scf_diis_release
     562             : 
     563           0 : END MODULE almo_scf_diis_types
     564             : 

Generated by: LCOV version 1.15