LCOV - code coverage report
Current view: top level - src - ct_methods.F (source / functions) Hit Total Coverage
Test: CP2K Regtests (git:3130539) Lines: 0 549 0.0 %
Date: 2025-05-14 06:57:18 Functions: 0 9 0.0 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------------------------!
       2             : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3             : !   Copyright 2000-2025 CP2K developers group <https://cp2k.org>                                   !
       4             : !                                                                                                  !
       5             : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6             : !--------------------------------------------------------------------------------------------------!
       7             : 
       8             : ! **************************************************************************************************
       9             : !> \brief Cayley transformation methods
      10             : !> \par History
      11             : !>       2011.06 created [Rustam Z Khaliullin]
      12             : !> \author Rustam Z Khaliullin
      13             : ! **************************************************************************************************
      14             : MODULE ct_methods
      15             :    USE cp_dbcsr_api,                    ONLY: &
      16             :         dbcsr_add, dbcsr_copy, dbcsr_create, dbcsr_desymmetrize, dbcsr_filter, dbcsr_finalize, &
      17             :         dbcsr_get_info, dbcsr_iterator_blocks_left, dbcsr_iterator_next_block, &
      18             :         dbcsr_iterator_readonly_start, dbcsr_iterator_start, dbcsr_iterator_stop, &
      19             :         dbcsr_iterator_type, dbcsr_multiply, dbcsr_put_block, dbcsr_release, dbcsr_scale, &
      20             :         dbcsr_set, dbcsr_transposed, dbcsr_type, dbcsr_type_no_symmetry, dbcsr_work_create
      21             :    USE cp_dbcsr_cholesky,               ONLY: cp_dbcsr_cholesky_decompose,&
      22             :                                               cp_dbcsr_cholesky_invert
      23             :    USE cp_dbcsr_contrib,                ONLY: dbcsr_add_on_diag,&
      24             :                                               dbcsr_dot,&
      25             :                                               dbcsr_frobenius_norm,&
      26             :                                               dbcsr_get_diag,&
      27             :                                               dbcsr_hadamard_product,&
      28             :                                               dbcsr_maxabs,&
      29             :                                               dbcsr_reserve_diag_blocks,&
      30             :                                               dbcsr_set_diag
      31             :    USE cp_dbcsr_diag,                   ONLY: cp_dbcsr_syevd
      32             :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      33             :                                               cp_logger_get_default_unit_nr,&
      34             :                                               cp_logger_type
      35             :    USE ct_types,                        ONLY: ct_step_env_type
      36             :    USE input_constants,                 ONLY: &
      37             :         cg_dai_yuan, cg_fletcher, cg_fletcher_reeves, cg_hager_zhang, cg_hestenes_stiefel, &
      38             :         cg_liu_storey, cg_polak_ribiere, cg_zero, tensor_orthogonal, tensor_up_down
      39             :    USE iterate_matrix,                  ONLY: matrix_sqrt_Newton_Schulz
      40             :    USE kinds,                           ONLY: dp
      41             :    USE machine,                         ONLY: m_walltime
      42             : #include "./base/base_uses.f90"
      43             : 
      44             :    IMPLICIT NONE
      45             : 
      46             :    PRIVATE
      47             : 
      48             :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'ct_methods'
      49             : 
      50             :    ! Public subroutines
      51             :    PUBLIC :: ct_step_execute, analytic_line_search, diagonalize_diagonal_blocks
      52             : 
      53             : CONTAINS
      54             : 
      55             : ! **************************************************************************************************
      56             : !> \brief Performs Cayley transformation
      57             : !> \param cts_env ...
      58             : !> \par History
      59             : !>       2011.06 created [Rustam Z Khaliullin]
      60             : !> \author Rustam Z Khaliullin
      61             : ! **************************************************************************************************
      62           0 :    SUBROUTINE ct_step_execute(cts_env)
      63             : 
      64             :       TYPE(ct_step_env_type)                             :: cts_env
      65             : 
      66             :       CHARACTER(len=*), PARAMETER                        :: routineN = 'ct_step_execute'
      67             : 
      68             :       INTEGER                                            :: handle, n, preconditioner_type, unit_nr
      69             :       REAL(KIND=dp)                                      :: gap_estimate, safety_margin
      70           0 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: evals
      71             :       TYPE(cp_logger_type), POINTER                      :: logger
      72             :       TYPE(dbcsr_type)                                   :: matrix_pp, matrix_pq, matrix_qp, &
      73             :                                                             matrix_qp_save, matrix_qq, oo1, &
      74             :                                                             oo1_sqrt, oo1_sqrt_inv, t_corr, tmp1, &
      75             :                                                             u_pp, u_qq
      76             : 
      77             : !TYPE(dbcsr_type)                :: rst_x1, rst_x2
      78             : !REAL(KIND=dp)                      :: ener_tmp
      79             : !TYPE(dbcsr_iterator_type)            :: iter
      80             : !INTEGER                            :: iblock_row,iblock_col,&
      81             : !                                      iblock_row_size,iblock_col_size
      82             : !REAL(KIND=dp), DIMENSION(:,:), POINTER :: data_p
      83             : 
      84           0 :       CALL timeset(routineN, handle)
      85             : 
      86           0 :       logger => cp_get_default_logger()
      87           0 :       IF (logger%para_env%is_source()) THEN
      88           0 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
      89             :       ELSE
      90             :          unit_nr = -1
      91             :       END IF
      92             : 
      93             :       ! check if all input is in place and flags are consistent
      94           0 :       IF (cts_env%update_q .AND. (.NOT. cts_env%update_p)) THEN
      95           0 :          CPABORT("q-update is possible only with p-update")
      96             :       END IF
      97             : 
      98           0 :       IF (cts_env%tensor_type .EQ. tensor_up_down) THEN
      99           0 :          CPABORT("riccati is not implemented for biorthogonal basis")
     100             :       END IF
     101             : 
     102           0 :       IF (.NOT. ASSOCIATED(cts_env%matrix_ks)) THEN
     103           0 :          CPABORT("KS matrix is not associated")
     104             :       END IF
     105             : 
     106           0 :       IF (cts_env%use_virt_orbs .AND. (.NOT. cts_env%use_occ_orbs)) THEN
     107           0 :          CPABORT("virtual orbs can be used only with occupied orbs")
     108             :       END IF
     109             : 
     110           0 :       IF (cts_env%use_occ_orbs) THEN
     111           0 :          IF (.NOT. ASSOCIATED(cts_env%matrix_t)) THEN
     112           0 :             CPABORT("T matrix is not associated")
     113             :          END IF
     114           0 :          IF (.NOT. ASSOCIATED(cts_env%matrix_qp_template)) THEN
     115           0 :             CPABORT("QP template is not associated")
     116             :          END IF
     117           0 :          IF (.NOT. ASSOCIATED(cts_env%matrix_pq_template)) THEN
     118           0 :             CPABORT("PQ template is not associated")
     119             :          END IF
     120             :       END IF
     121             : 
     122           0 :       IF (cts_env%use_virt_orbs) THEN
     123           0 :          IF (.NOT. ASSOCIATED(cts_env%matrix_v)) THEN
     124           0 :             CPABORT("V matrix is not associated")
     125             :          END IF
     126             :       ELSE
     127           0 :          IF (.NOT. ASSOCIATED(cts_env%matrix_p)) THEN
     128           0 :             CPABORT("P matrix is not associated")
     129             :          END IF
     130             :       END IF
     131             : 
     132           0 :       IF (cts_env%tensor_type .NE. tensor_up_down .AND. &
     133             :           cts_env%tensor_type .NE. tensor_orthogonal) THEN
     134           0 :          CPABORT("illegal tensor flag")
     135             :       END IF
     136             : 
     137             :       ! start real calculations
     138           0 :       IF (cts_env%use_occ_orbs) THEN
     139             : 
     140             :          ! create matrices for various ks blocks
     141             :          CALL dbcsr_create(matrix_pp, &
     142             :                            template=cts_env%p_index_up, &
     143           0 :                            matrix_type=dbcsr_type_no_symmetry)
     144             :          CALL dbcsr_create(matrix_qp, &
     145             :                            template=cts_env%matrix_qp_template, &
     146           0 :                            matrix_type=dbcsr_type_no_symmetry)
     147             :          CALL dbcsr_create(matrix_qq, &
     148             :                            template=cts_env%q_index_up, &
     149           0 :                            matrix_type=dbcsr_type_no_symmetry)
     150             :          CALL dbcsr_create(matrix_pq, &
     151             :                            template=cts_env%matrix_pq_template, &
     152           0 :                            matrix_type=dbcsr_type_no_symmetry)
     153             : 
     154             :          ! create the residue matrix
     155             :          CALL dbcsr_create(cts_env%matrix_res, &
     156           0 :                            template=cts_env%matrix_qp_template)
     157             : 
     158             :          CALL assemble_ks_qp_blocks(cts_env%matrix_ks, &
     159             :                                     cts_env%matrix_p, &
     160             :                                     cts_env%matrix_t, &
     161             :                                     cts_env%matrix_v, &
     162             :                                     cts_env%q_index_down, &
     163             :                                     cts_env%p_index_up, &
     164             :                                     cts_env%q_index_up, &
     165             :                                     matrix_pp, &
     166             :                                     matrix_qq, &
     167             :                                     matrix_qp, &
     168             :                                     matrix_pq, &
     169             :                                     cts_env%tensor_type, &
     170             :                                     cts_env%use_virt_orbs, &
     171           0 :                                     cts_env%eps_filter)
     172             : 
     173             :          ! create a matrix of single-excitation amplitudes
     174             :          CALL dbcsr_create(cts_env%matrix_x, &
     175           0 :                            template=cts_env%matrix_qp_template)
     176           0 :          IF (ASSOCIATED(cts_env%matrix_x_guess)) THEN
     177             :             CALL dbcsr_copy(cts_env%matrix_x, &
     178           0 :                             cts_env%matrix_x_guess)
     179           0 :             IF (cts_env%tensor_type .EQ. tensor_orthogonal) THEN
     180             :                ! bring x from contravariant-covariant representation
     181             :                ! to the orthogonal/cholesky representation
     182             :                ! use res as temporary storage
     183             :                CALL dbcsr_multiply("N", "N", 1.0_dp, cts_env%q_index_down, &
     184             :                                    cts_env%matrix_x, 0.0_dp, cts_env%matrix_res, &
     185           0 :                                    filter_eps=cts_env%eps_filter)
     186             :                CALL dbcsr_multiply("N", "N", 1.0_dp, cts_env%matrix_res, &
     187             :                                    cts_env%p_index_up, 0.0_dp, &
     188             :                                    cts_env%matrix_x, &
     189           0 :                                    filter_eps=cts_env%eps_filter)
     190             :             END IF
     191             :          ELSE
     192             :             ! set amplitudes to zero
     193           0 :             CALL dbcsr_set(cts_env%matrix_x, 0.0_dp)
     194             :          END IF
     195             : 
     196             :          !SELECT CASE (cts_env%preconditioner_type)
     197             :          !CASE (prec_eigenvector_blocks,prec_eigenvector_full)
     198           0 :          preconditioner_type = 1
     199           0 :          safety_margin = 2.0_dp
     200           0 :          gap_estimate = 0.0001_dp
     201             :          SELECT CASE (preconditioner_type)
     202             :          CASE (1, 2)
     203             : !RZK-warning diagonalization works only with orthogonal tensor!!!
     204             :             ! find a better basis by diagonalizing diagonal blocks
     205             :             ! first pp
     206             :             CALL dbcsr_create(u_pp, template=matrix_pp, &
     207           0 :                               matrix_type=dbcsr_type_no_symmetry)
     208             :             !IF (cts_env%preconditioner_type.eq.prec_eigenvector_full) THEN
     209             :             IF (.TRUE.) THEN
     210           0 :                CALL dbcsr_get_info(matrix_pp, nfullrows_total=n)
     211           0 :                ALLOCATE (evals(n))
     212             :                CALL cp_dbcsr_syevd(matrix_pp, u_pp, evals, &
     213           0 :                                    cts_env%para_env, cts_env%blacs_env)
     214           0 :                DEALLOCATE (evals)
     215             :             ELSE
     216             :                CALL diagonalize_diagonal_blocks(matrix_pp, u_pp)
     217             :             END IF
     218             :             ! and now qq
     219             :             CALL dbcsr_create(u_qq, template=matrix_qq, &
     220           0 :                               matrix_type=dbcsr_type_no_symmetry)
     221             :             !IF (cts_env%preconditioner_type.eq.prec_eigenvector_full) THEN
     222             :             IF (.TRUE.) THEN
     223           0 :                CALL dbcsr_get_info(matrix_qq, nfullrows_total=n)
     224           0 :                ALLOCATE (evals(n))
     225             :                CALL cp_dbcsr_syevd(matrix_qq, u_qq, evals, &
     226           0 :                                    cts_env%para_env, cts_env%blacs_env)
     227           0 :                DEALLOCATE (evals)
     228             :             ELSE
     229             :                CALL diagonalize_diagonal_blocks(matrix_qq, u_qq)
     230             :             END IF
     231             : 
     232             :             ! apply the transformation to all matrices
     233             :             CALL matrix_forward_transform(matrix_pp, u_pp, u_pp, &
     234           0 :                                           cts_env%eps_filter)
     235             :             CALL matrix_forward_transform(matrix_qq, u_qq, u_qq, &
     236           0 :                                           cts_env%eps_filter)
     237             :             CALL matrix_forward_transform(matrix_qp, u_qq, u_pp, &
     238           0 :                                           cts_env%eps_filter)
     239             :             CALL matrix_forward_transform(matrix_pq, u_pp, u_qq, &
     240           0 :                                           cts_env%eps_filter)
     241             :             CALL matrix_forward_transform(cts_env%matrix_x, u_qq, u_pp, &
     242           0 :                                           cts_env%eps_filter)
     243             : 
     244           0 :             IF (cts_env%max_iter .GE. 0) THEN
     245             : 
     246             :                CALL solve_riccati_equation( &
     247             :                   pp=matrix_pp, &
     248             :                   qq=matrix_qq, &
     249             :                   qp=matrix_qp, &
     250             :                   pq=matrix_pq, &
     251             :                   x=cts_env%matrix_x, &
     252             :                   res=cts_env%matrix_res, &
     253             :                   neglect_quadratic_term=cts_env%neglect_quadratic_term, &
     254             :                   conjugator=cts_env%conjugator, &
     255             :                   max_iter=cts_env%max_iter, &
     256             :                   eps_convergence=cts_env%eps_convergence, &
     257             :                   eps_filter=cts_env%eps_filter, &
     258           0 :                   converged=cts_env%converged)
     259             : 
     260           0 :                IF (cts_env%converged) THEN
     261             :                   !IF (unit_nr>0) THEN
     262             :                   !   WRITE(unit_nr,*)
     263             :                   !   WRITE(unit_nr,'(T6,A)') &
     264             :                   !         "RICCATI equations solved"
     265             :                   !   CALL m_flush(unit_nr)
     266             :                   !ENDIF
     267             :                ELSE
     268           0 :                   CPABORT("RICCATI: CG algorithm has NOT converged")
     269             :                END IF
     270             : 
     271             :             END IF
     272             : 
     273           0 :             IF (cts_env%calculate_energy_corr) THEN
     274             : 
     275           0 :                CALL dbcsr_dot(matrix_qp, cts_env%matrix_x, cts_env%energy_correction)
     276             : 
     277             :             END IF
     278             : 
     279           0 :             CALL dbcsr_release(matrix_pp)
     280           0 :             CALL dbcsr_release(matrix_qp)
     281           0 :             CALL dbcsr_release(matrix_qq)
     282           0 :             CALL dbcsr_release(matrix_pq)
     283             : 
     284             :             ! back-transform to the original basis
     285             :             CALL matrix_backward_transform(cts_env%matrix_x, u_qq, &
     286           0 :                                            u_pp, cts_env%eps_filter)
     287             : 
     288           0 :             CALL dbcsr_release(u_qq)
     289           0 :             CALL dbcsr_release(u_pp)
     290             : 
     291             :             !CASE (prec_cholesky_inverse)
     292             :          CASE (3)
     293             : 
     294             : ! RZK-warning implemented only for orthogonal tensors!!!
     295             : ! generalization to up_down should be easy
     296             :             CALL dbcsr_create(u_pp, template=matrix_pp, &
     297             :                               matrix_type=dbcsr_type_no_symmetry)
     298             :             CALL dbcsr_copy(u_pp, matrix_pp)
     299             :             CALL dbcsr_scale(u_pp, -1.0_dp)
     300             :             CALL dbcsr_add_on_diag(u_pp, &
     301             :                                    ABS(safety_margin*gap_estimate))
     302             :             CALL cp_dbcsr_cholesky_decompose(u_pp, &
     303             :                                              para_env=cts_env%para_env, &
     304             :                                              blacs_env=cts_env%blacs_env)
     305             :             CALL cp_dbcsr_cholesky_invert(u_pp, &
     306             :                                           para_env=cts_env%para_env, &
     307             :                                           blacs_env=cts_env%blacs_env, &
     308             :                                           uplo_to_full=.TRUE.)
     309             :             !CALL dbcsr_scale(u_pp,-1.0_dp)
     310             : 
     311             :             CALL dbcsr_create(u_qq, template=matrix_qq, &
     312             :                               matrix_type=dbcsr_type_no_symmetry)
     313             :             CALL dbcsr_copy(u_qq, matrix_qq)
     314             :             CALL dbcsr_add_on_diag(u_qq, &
     315             :                                    ABS(safety_margin*gap_estimate))
     316             :             CALL cp_dbcsr_cholesky_decompose(u_qq, &
     317             :                                              para_env=cts_env%para_env, &
     318             :                                              blacs_env=cts_env%blacs_env)
     319             :             CALL cp_dbcsr_cholesky_invert(u_qq, &
     320             :                                           para_env=cts_env%para_env, &
     321             :                                           blacs_env=cts_env%blacs_env, &
     322             :                                           uplo_to_full=.TRUE.)
     323             : 
     324             :             ! transform all riccati matrices (left-right preconditioner)
     325             :             CALL dbcsr_create(tmp1, template=matrix_qq, &
     326             :                               matrix_type=dbcsr_type_no_symmetry)
     327             :             CALL dbcsr_multiply("N", "N", 1.0_dp, u_qq, &
     328             :                                 matrix_qq, 0.0_dp, tmp1, &
     329             :                                 filter_eps=cts_env%eps_filter)
     330             :             CALL dbcsr_copy(matrix_qq, tmp1)
     331             :             CALL dbcsr_release(tmp1)
     332             : 
     333             :             CALL dbcsr_create(tmp1, template=matrix_pp, &
     334             :                               matrix_type=dbcsr_type_no_symmetry)
     335             :             CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_pp, &
     336             :                                 u_pp, 0.0_dp, tmp1, &
     337             :                                 filter_eps=cts_env%eps_filter)
     338             :             CALL dbcsr_copy(matrix_pp, tmp1)
     339             :             CALL dbcsr_release(tmp1)
     340             : 
     341             :             CALL dbcsr_create(matrix_qp_save, template=matrix_qp, &
     342             :                               matrix_type=dbcsr_type_no_symmetry)
     343             :             CALL dbcsr_copy(matrix_qp_save, matrix_qp)
     344             : 
     345             :             CALL dbcsr_create(tmp1, template=matrix_qp, &
     346             :                               matrix_type=dbcsr_type_no_symmetry)
     347             :             CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_qp, &
     348             :                                 u_pp, 0.0_dp, tmp1, &
     349             :                                 filter_eps=cts_env%eps_filter)
     350             :             CALL dbcsr_multiply("N", "N", 1.0_dp, u_qq, tmp1, &
     351             :                                 0.0_dp, matrix_qp, &
     352             :                                 filter_eps=cts_env%eps_filter)
     353             :             CALL dbcsr_release(tmp1)
     354             : !CALL dbcsr_print(matrix_qq)
     355             : !CALL dbcsr_print(matrix_qp)
     356             : !CALL dbcsr_print(matrix_pp)
     357             : 
     358             :             IF (cts_env%max_iter .GE. 0) THEN
     359             : 
     360             :                CALL solve_riccati_equation( &
     361             :                   pp=matrix_pp, &
     362             :                   qq=matrix_qq, &
     363             :                   qp=matrix_qp, &
     364             :                   pq=matrix_pq, &
     365             :                   oo=u_pp, &
     366             :                   vv=u_qq, &
     367             :                   x=cts_env%matrix_x, &
     368             :                   res=cts_env%matrix_res, &
     369             :                   neglect_quadratic_term=cts_env%neglect_quadratic_term, &
     370             :                   conjugator=cts_env%conjugator, &
     371             :                   max_iter=cts_env%max_iter, &
     372             :                   eps_convergence=cts_env%eps_convergence, &
     373             :                   eps_filter=cts_env%eps_filter, &
     374             :                   converged=cts_env%converged)
     375             : 
     376             :                IF (cts_env%converged) THEN
     377             :                   !IF (unit_nr>0) THEN
     378             :                   !   WRITE(unit_nr,*)
     379             :                   !   WRITE(unit_nr,'(T6,A)') &
     380             :                   !         "RICCATI equations solved"
     381             :                   !   CALL m_flush(unit_nr)
     382             :                   !ENDIF
     383             :                ELSE
     384             :                   CPABORT("RICCATI: CG algorithm has NOT converged")
     385             :                END IF
     386             : 
     387             :             END IF
     388             : 
     389             :             IF (cts_env%calculate_energy_corr) THEN
     390             : 
     391             :                CALL dbcsr_dot(matrix_qp_save, cts_env%matrix_x, cts_env%energy_correction)
     392             : 
     393             :             END IF
     394             :             CALL dbcsr_release(matrix_qp_save)
     395             : 
     396             :             CALL dbcsr_release(matrix_pp)
     397             :             CALL dbcsr_release(matrix_qp)
     398             :             CALL dbcsr_release(matrix_qq)
     399             :             CALL dbcsr_release(matrix_pq)
     400             : 
     401             :             CALL dbcsr_release(u_qq)
     402             :             CALL dbcsr_release(u_pp)
     403             : 
     404             :          CASE DEFAULT
     405             :             CPABORT("illegal preconditioner type")
     406             :          END SELECT ! preconditioner type
     407             : 
     408           0 :          IF (cts_env%update_p) THEN
     409             : 
     410           0 :             IF (cts_env%tensor_type .EQ. tensor_up_down) THEN
     411           0 :                CPABORT("orbital update is NYI for this tensor type")
     412             :             END IF
     413             : 
     414             :             ! transform occupied orbitals
     415             :             ! in a way that preserves the overlap metric
     416             :             CALL dbcsr_create(oo1, &
     417             :                               template=cts_env%p_index_up, &
     418           0 :                               matrix_type=dbcsr_type_no_symmetry)
     419             :             CALL dbcsr_create(oo1_sqrt_inv, &
     420           0 :                               template=oo1)
     421             :             CALL dbcsr_create(oo1_sqrt, &
     422           0 :                               template=oo1)
     423             : 
     424             :             ! Compute (1+tr(X).X)^(-1/2)_up_down
     425             :             CALL dbcsr_multiply("T", "N", 1.0_dp, cts_env%matrix_x, &
     426             :                                 cts_env%matrix_x, 0.0_dp, oo1, &
     427           0 :                                 filter_eps=cts_env%eps_filter)
     428           0 :             CALL dbcsr_add_on_diag(oo1, 1.0_dp)
     429             :             CALL matrix_sqrt_Newton_Schulz(oo1_sqrt, &
     430             :                                            oo1_sqrt_inv, &
     431             :                                            oo1, &
     432             :                                            !if cholesky is used then sqrt
     433             :                                            !guess cannot be provided
     434             :                                            !matrix_sqrt_inv_guess=cts_env%p_index_up,&
     435             :                                            !matrix_sqrt_guess=cts_env%p_index_down,&
     436             :                                            threshold=cts_env%eps_filter, &
     437             :                                            order=cts_env%order_lanczos, &
     438             :                                            eps_lanczos=cts_env%eps_lancsoz, &
     439           0 :                                            max_iter_lanczos=cts_env%max_iter_lanczos)
     440             :             CALL dbcsr_multiply("N", "N", 1.0_dp, cts_env%p_index_up, &
     441             :                                 oo1_sqrt_inv, 0.0_dp, oo1, &
     442           0 :                                 filter_eps=cts_env%eps_filter)
     443             :             CALL dbcsr_multiply("N", "N", 1.0_dp, oo1, &
     444             :                                 cts_env%p_index_down, 0.0_dp, oo1_sqrt, &
     445           0 :                                 filter_eps=cts_env%eps_filter)
     446           0 :             CALL dbcsr_release(oo1)
     447           0 :             CALL dbcsr_release(oo1_sqrt_inv)
     448             : 
     449             :             ! bring x to contravariant-covariant representation now
     450             :             CALL dbcsr_create(matrix_qp, &
     451             :                               template=cts_env%matrix_qp_template, &
     452           0 :                               matrix_type=dbcsr_type_no_symmetry)
     453             :             CALL dbcsr_multiply("N", "N", 1.0_dp, cts_env%q_index_up, &
     454             :                                 cts_env%matrix_x, 0.0_dp, matrix_qp, &
     455           0 :                                 filter_eps=cts_env%eps_filter)
     456             :             CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_qp, &
     457             :                                 cts_env%p_index_down, 0.0_dp, &
     458             :                                 cts_env%matrix_x, &
     459           0 :                                 filter_eps=cts_env%eps_filter)
     460           0 :             CALL dbcsr_release(matrix_qp)
     461             : 
     462             :             ! update T=T+X or T=T+V.X (whichever is appropriate)
     463           0 :             CALL dbcsr_create(t_corr, template=cts_env%matrix_t)
     464           0 :             IF (cts_env%use_virt_orbs) THEN
     465             :                CALL dbcsr_multiply("N", "N", 1.0_dp, cts_env%matrix_v, &
     466             :                                    cts_env%matrix_x, 0.0_dp, t_corr, &
     467           0 :                                    filter_eps=cts_env%eps_filter)
     468             :                CALL dbcsr_add(cts_env%matrix_t, t_corr, &
     469           0 :                               1.0_dp, 1.0_dp)
     470             :             ELSE
     471             :                CALL dbcsr_add(cts_env%matrix_t, cts_env%matrix_x, &
     472           0 :                               1.0_dp, 1.0_dp)
     473             :             END IF
     474             :             ! adjust T so the metric is preserved: T=(T+X).(1+tr(X).X)^(-1/2)
     475             :             CALL dbcsr_multiply("N", "N", 1.0_dp, cts_env%matrix_t, oo1_sqrt, &
     476           0 :                                 0.0_dp, t_corr, filter_eps=cts_env%eps_filter)
     477           0 :             CALL dbcsr_copy(cts_env%matrix_t, t_corr)
     478             : 
     479           0 :             CALL dbcsr_release(t_corr)
     480           0 :             CALL dbcsr_release(oo1_sqrt)
     481             : 
     482             :          ELSE ! do not update p
     483             : 
     484           0 :             IF (cts_env%tensor_type .EQ. tensor_orthogonal) THEN
     485             :                ! bring x to contravariant-covariant representation
     486             :                CALL dbcsr_create(matrix_qp, &
     487             :                                  template=cts_env%matrix_qp_template, &
     488           0 :                                  matrix_type=dbcsr_type_no_symmetry)
     489             :                CALL dbcsr_multiply("N", "N", 1.0_dp, cts_env%q_index_up, &
     490             :                                    cts_env%matrix_x, 0.0_dp, matrix_qp, &
     491           0 :                                    filter_eps=cts_env%eps_filter)
     492             :                CALL dbcsr_multiply("N", "N", 1.0_dp, matrix_qp, &
     493             :                                    cts_env%p_index_down, 0.0_dp, &
     494             :                                    cts_env%matrix_x, &
     495           0 :                                    filter_eps=cts_env%eps_filter)
     496           0 :                CALL dbcsr_release(matrix_qp)
     497             :             END IF
     498             : 
     499             :          END IF
     500             : 
     501             :       ELSE
     502           0 :          CPABORT("illegal occ option")
     503             :       END IF
     504             : 
     505           0 :       CALL timestop(handle)
     506             : 
     507           0 :    END SUBROUTINE ct_step_execute
     508             : 
     509             : ! **************************************************************************************************
     510             : !> \brief computes oo, ov, vo, and vv blocks of the ks matrix
     511             : !> \param ks ...
     512             : !> \param p ...
     513             : !> \param t ...
     514             : !> \param v ...
     515             : !> \param q_index_down ...
     516             : !> \param p_index_up ...
     517             : !> \param q_index_up ...
     518             : !> \param pp ...
     519             : !> \param qq ...
     520             : !> \param qp ...
     521             : !> \param pq ...
     522             : !> \param tensor_type ...
     523             : !> \param use_virt_orbs ...
     524             : !> \param eps_filter ...
     525             : !> \par History
     526             : !>       2011.06 created [Rustam Z Khaliullin]
     527             : !> \author Rustam Z Khaliullin
     528             : ! **************************************************************************************************
     529           0 :    SUBROUTINE assemble_ks_qp_blocks(ks, p, t, v, q_index_down, &
     530             :                                     p_index_up, q_index_up, pp, qq, qp, pq, tensor_type, use_virt_orbs, eps_filter)
     531             : 
     532             :       TYPE(dbcsr_type), INTENT(IN)                       :: ks, p, t, v, q_index_down, p_index_up, &
     533             :                                                             q_index_up
     534             :       TYPE(dbcsr_type), INTENT(OUT)                      :: pp, qq, qp, pq
     535             :       INTEGER, INTENT(IN)                                :: tensor_type
     536             :       LOGICAL, INTENT(IN)                                :: use_virt_orbs
     537             :       REAL(KIND=dp), INTENT(IN)                          :: eps_filter
     538             : 
     539             :       CHARACTER(len=*), PARAMETER :: routineN = 'assemble_ks_qp_blocks'
     540             : 
     541             :       INTEGER                                            :: handle
     542             :       LOGICAL                                            :: library_fixed
     543             :       TYPE(dbcsr_type)                                   :: kst, ksv, no, on, oo, q_index_up_nosym, &
     544             :                                                             sp, spf, t_or, v_or
     545             : 
     546           0 :       CALL timeset(routineN, handle)
     547             : 
     548           0 :       IF (use_virt_orbs) THEN
     549             : 
     550             :          ! orthogonalize the orbitals
     551           0 :          CALL dbcsr_create(t_or, template=t)
     552           0 :          CALL dbcsr_create(v_or, template=v)
     553             :          CALL dbcsr_multiply("N", "N", 1.0_dp, t, p_index_up, &
     554           0 :                              0.0_dp, t_or, filter_eps=eps_filter)
     555             :          CALL dbcsr_multiply("N", "N", 1.0_dp, v, q_index_up, &
     556           0 :                              0.0_dp, v_or, filter_eps=eps_filter)
     557             : 
     558             :          ! KS.T
     559           0 :          CALL dbcsr_create(kst, template=t)
     560             :          CALL dbcsr_multiply("N", "N", 1.0_dp, ks, t_or, &
     561           0 :                              0.0_dp, kst, filter_eps=eps_filter)
     562             :          ! pp=tr(T)*KS.T
     563             :          CALL dbcsr_multiply("T", "N", 1.0_dp, t_or, kst, &
     564           0 :                              0.0_dp, pp, filter_eps=eps_filter)
     565             :          ! qp=tr(V)*KS.T
     566             :          CALL dbcsr_multiply("T", "N", 1.0_dp, v_or, kst, &
     567           0 :                              0.0_dp, qp, filter_eps=eps_filter)
     568           0 :          CALL dbcsr_release(kst)
     569             : 
     570             :          ! KS.V
     571           0 :          CALL dbcsr_create(ksv, template=v)
     572             :          CALL dbcsr_multiply("N", "N", 1.0_dp, ks, v_or, &
     573           0 :                              0.0_dp, ksv, filter_eps=eps_filter)
     574             :          ! tr(T)*KS.V
     575             :          CALL dbcsr_multiply("T", "N", 1.0_dp, t_or, ksv, &
     576           0 :                              0.0_dp, pq, filter_eps=eps_filter)
     577             :          ! tr(V)*KS.V
     578             :          CALL dbcsr_multiply("T", "N", 1.0_dp, v_or, ksv, &
     579           0 :                              0.0_dp, qq, filter_eps=eps_filter)
     580           0 :          CALL dbcsr_release(ksv)
     581             : 
     582           0 :          CALL dbcsr_release(t_or)
     583           0 :          CALL dbcsr_release(v_or)
     584             : 
     585             :       ELSE ! no virtuals, use projected AOs
     586             : 
     587             : ! THIS PROCEDURE HAS NOT BEEN UPDATED FOR CHOLESKY p/q_index_up/down
     588             :          CALL dbcsr_create(sp, template=q_index_down, &
     589           0 :                            matrix_type=dbcsr_type_no_symmetry)
     590             :          CALL dbcsr_create(spf, template=q_index_down, &
     591           0 :                            matrix_type=dbcsr_type_no_symmetry)
     592             : 
     593             :          ! qp=KS*T
     594             :          CALL dbcsr_multiply("N", "N", 1.0_dp, ks, t, 0.0_dp, qp, &
     595           0 :                              filter_eps=eps_filter)
     596             :          ! pp=tr(T)*KS.T
     597             :          CALL dbcsr_multiply("T", "N", 1.0_dp, t, qp, 0.0_dp, pp, &
     598           0 :                              filter_eps=eps_filter)
     599             :          ! sp=-S_*P
     600             :          CALL dbcsr_multiply("N", "N", -1.0_dp, q_index_down, p, 0.0_dp, sp, &
     601           0 :                              filter_eps=eps_filter)
     602             : 
     603             :          ! sp=1/S^-S_.P
     604           0 :          SELECT CASE (tensor_type)
     605             :          CASE (tensor_up_down)
     606           0 :             CALL dbcsr_add_on_diag(sp, 1.0_dp)
     607             :          CASE (tensor_orthogonal)
     608             :             CALL dbcsr_create(q_index_up_nosym, template=q_index_up, &
     609           0 :                               matrix_type=dbcsr_type_no_symmetry)
     610           0 :             CALL dbcsr_desymmetrize(q_index_up, q_index_up_nosym)
     611           0 :             CALL dbcsr_add(sp, q_index_up_nosym, 1.0_dp, 1.0_dp)
     612           0 :             CALL dbcsr_release(q_index_up_nosym)
     613             :          END SELECT
     614             : 
     615             :          ! spf=(1/S^-S_.P)*KS
     616             :          CALL dbcsr_multiply("N", "N", 1.0_dp, sp, ks, 0.0_dp, spf, &
     617           0 :                              filter_eps=eps_filter)
     618             : 
     619             :          ! qp=spf*T
     620             :          CALL dbcsr_multiply("N", "N", 1.0_dp, spf, t, 0.0_dp, qp, &
     621           0 :                              filter_eps=eps_filter)
     622             : 
     623           0 :          SELECT CASE (tensor_type)
     624             :          CASE (tensor_up_down)
     625             :             ! pq=tr(qp)
     626           0 :             CALL dbcsr_transposed(pq, qp, transpose_distribution=.FALSE.)
     627             :          CASE (tensor_orthogonal)
     628             :             ! pq=sig^.tr(qp)
     629             :             CALL dbcsr_multiply("N", "T", 1.0_dp, p_index_up, qp, 0.0_dp, pq, &
     630           0 :                                 filter_eps=eps_filter)
     631           0 :             library_fixed = .FALSE.
     632           0 :             IF (library_fixed) THEN
     633             :                CALL dbcsr_transposed(qp, pq, transpose_distribution=.FALSE.)
     634             :             ELSE
     635             :                CALL dbcsr_create(no, template=qp, &
     636           0 :                                  matrix_type=dbcsr_type_no_symmetry)
     637             :                CALL dbcsr_multiply("N", "N", 1.0_dp, qp, p_index_up, 0.0_dp, no, &
     638           0 :                                    filter_eps=eps_filter)
     639           0 :                CALL dbcsr_copy(qp, no)
     640           0 :                CALL dbcsr_release(no)
     641             :             END IF
     642             :          END SELECT
     643             : 
     644             :          ! qq=spf*tr(sp)
     645             :          CALL dbcsr_multiply("N", "T", 1.0_dp, spf, sp, 0.0_dp, qq, &
     646           0 :                              filter_eps=eps_filter)
     647             : 
     648           0 :          SELECT CASE (tensor_type)
     649             :          CASE (tensor_up_down)
     650             : 
     651             :             CALL dbcsr_create(oo, template=pp, &
     652           0 :                               matrix_type=dbcsr_type_no_symmetry)
     653             :             CALL dbcsr_create(no, template=qp, &
     654           0 :                               matrix_type=dbcsr_type_no_symmetry)
     655             : 
     656             :             ! first index up
     657             :             CALL dbcsr_multiply("N", "N", 1.0_dp, q_index_up, qq, 0.0_dp, spf, &
     658           0 :                                 filter_eps=eps_filter)
     659           0 :             CALL dbcsr_copy(qq, spf)
     660             :             CALL dbcsr_multiply("N", "N", 1.0_dp, q_index_up, qp, 0.0_dp, no, &
     661           0 :                                 filter_eps=eps_filter)
     662           0 :             CALL dbcsr_copy(qp, no)
     663             :             CALL dbcsr_multiply("N", "N", 1.0_dp, p_index_up, pp, 0.0_dp, oo, &
     664           0 :                                 filter_eps=eps_filter)
     665           0 :             CALL dbcsr_copy(pp, oo)
     666             :             CALL dbcsr_multiply("N", "N", 1.0_dp, p_index_up, pq, 0.0_dp, on, &
     667           0 :                                 filter_eps=eps_filter)
     668           0 :             CALL dbcsr_copy(pq, on)
     669             : 
     670           0 :             CALL dbcsr_release(no)
     671           0 :             CALL dbcsr_release(oo)
     672             : 
     673             :          CASE (tensor_orthogonal)
     674             : 
     675             :             CALL dbcsr_create(oo, template=pp, &
     676           0 :                               matrix_type=dbcsr_type_no_symmetry)
     677             : 
     678             :             ! both indeces up in the pp block
     679             :             CALL dbcsr_multiply("N", "N", 1.0_dp, p_index_up, pp, 0.0_dp, oo, &
     680           0 :                                 filter_eps=eps_filter)
     681             :             CALL dbcsr_multiply("N", "N", 1.0_dp, oo, p_index_up, 0.0_dp, pp, &
     682           0 :                                 filter_eps=eps_filter)
     683             : 
     684           0 :             CALL dbcsr_release(oo)
     685             : 
     686             :          END SELECT
     687             : 
     688           0 :          CALL dbcsr_release(sp)
     689           0 :          CALL dbcsr_release(spf)
     690             : 
     691             :       END IF
     692             : 
     693           0 :       CALL timestop(handle)
     694             : 
     695           0 :    END SUBROUTINE assemble_ks_qp_blocks
     696             : 
     697             : ! **************************************************************************************************
     698             : !> \brief Solves the generalized Riccati or Sylvester eqation
     699             : !>        using the preconditioned conjugate gradient algorithm
     700             : !>          qp + qq.x.oo - vv.x.pp - vv.x.pq.x.oo = 0 [oo and vv are optional]
     701             : !>          qp + qq.x - x.pp - x.pq.x = 0
     702             : !> \param pp ...
     703             : !> \param qq ...
     704             : !> \param qp ...
     705             : !> \param pq ...
     706             : !> \param oo ...
     707             : !> \param vv ...
     708             : !> \param x ...
     709             : !> \param res ...
     710             : !> \param neglect_quadratic_term ...
     711             : !> \param conjugator ...
     712             : !> \param max_iter ...
     713             : !> \param eps_convergence ...
     714             : !> \param eps_filter ...
     715             : !> \param converged ...
     716             : !> \par History
     717             : !>       2011.06 created [Rustam Z Khaliullin]
     718             : !>       2011.11 generalized [Rustam Z Khaliullin]
     719             : !> \author Rustam Z Khaliullin
     720             : ! **************************************************************************************************
     721           0 :    RECURSIVE SUBROUTINE solve_riccati_equation(pp, qq, qp, pq, oo, vv, x, res, &
     722             :                                                neglect_quadratic_term, &
     723             :                                                conjugator, max_iter, eps_convergence, eps_filter, &
     724             :                                                converged)
     725             : 
     726             :       TYPE(dbcsr_type), INTENT(IN)                       :: pp, qq
     727             :       TYPE(dbcsr_type), INTENT(INOUT)                    :: qp
     728             :       TYPE(dbcsr_type), INTENT(IN)                       :: pq
     729             :       TYPE(dbcsr_type), INTENT(IN), OPTIONAL             :: oo, vv
     730             :       TYPE(dbcsr_type), INTENT(INOUT)                    :: x
     731             :       TYPE(dbcsr_type), INTENT(OUT)                      :: res
     732             :       LOGICAL, INTENT(IN)                                :: neglect_quadratic_term
     733             :       INTEGER, INTENT(IN)                                :: conjugator, max_iter
     734             :       REAL(KIND=dp), INTENT(IN)                          :: eps_convergence, eps_filter
     735             :       LOGICAL, INTENT(OUT)                               :: converged
     736             : 
     737             :       CHARACTER(len=*), PARAMETER :: routineN = 'solve_riccati_equation'
     738             : 
     739             :       INTEGER                                            :: handle, istep, iteration, nsteps, &
     740             :                                                             unit_nr, update_prec_freq
     741             :       LOGICAL                                            :: prepare_to_exit, present_oo, present_vv, &
     742             :                                                             quadratic_term, restart_conjugator
     743             :       REAL(KIND=dp)                                      :: best_norm, best_step_size, beta, c0, c1, &
     744             :                                                             c2, c3, denom, kappa, numer, &
     745             :                                                             obj_function, t1, t2, tau
     746             :       REAL(KIND=dp), DIMENSION(3)                        :: step_size
     747             :       TYPE(cp_logger_type), POINTER                      :: logger
     748             :       TYPE(dbcsr_type)                                   :: aux1, aux2, grad, m, n, oo1, oo2, prec, &
     749             :                                                             res_trial, step, step_oo, vv_step
     750             : 
     751             : !TYPE(dbcsr_type)                      :: qqqq, pppp, zero_pq, zero_qp
     752             : 
     753           0 :       CALL timeset(routineN, handle)
     754             : 
     755           0 :       logger => cp_get_default_logger()
     756           0 :       IF (logger%para_env%is_source()) THEN
     757           0 :          unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
     758             :       ELSE
     759             :          unit_nr = -1
     760             :       END IF
     761             : 
     762           0 :       t1 = m_walltime()
     763             : 
     764             : !IF (level.gt.5) THEN
     765             : !  CPErrorMessage(cp_failure_level,routineP,"recursion level is too high")
     766             : !  CPPrecondition(.FALSE.,cp_failure_level,routineP,failure)
     767             : !ENDIF
     768             : !IF (unit_nr>0) THEN
     769             : !   WRITE(unit_nr,*) &
     770             : !      "========== LEVEL ",level,"=========="
     771             : !ENDIF
     772             : !CALL dbcsr_print(qq)
     773             : !CALL dbcsr_print(pp)
     774             : !CALL dbcsr_print(qp)
     775             : !!CALL dbcsr_print(pq)
     776             : !IF (unit_nr>0) THEN
     777             : !   WRITE(unit_nr,*) &
     778             : !      "====== END LEVEL ",level,"=========="
     779             : !ENDIF
     780             : 
     781           0 :       quadratic_term = .NOT. neglect_quadratic_term
     782           0 :       present_oo = PRESENT(oo)
     783           0 :       present_vv = PRESENT(vv)
     784             : 
     785             :       ! create aux1 matrix and init
     786           0 :       CALL dbcsr_create(aux1, template=pp)
     787           0 :       CALL dbcsr_copy(aux1, pp)
     788           0 :       CALL dbcsr_scale(aux1, -1.0_dp)
     789             : 
     790             :       ! create aux2 matrix and init
     791           0 :       CALL dbcsr_create(aux2, template=qq)
     792           0 :       CALL dbcsr_copy(aux2, qq)
     793             : 
     794             :       ! create the gradient matrix and init
     795           0 :       CALL dbcsr_create(grad, template=x)
     796           0 :       CALL dbcsr_set(grad, 0.0_dp)
     797             : 
     798             :       ! create a preconditioner
     799             :       ! RZK-warning how to apply it to up_down tensor?
     800           0 :       CALL dbcsr_create(prec, template=x)
     801             :       !CALL create_preconditioner(prec,aux1,aux2,qp,res,tensor_type,eps_filter)
     802             :       !CALL dbcsr_set(prec,1.0_dp)
     803             : 
     804             :       ! create the step matrix and init
     805           0 :       CALL dbcsr_create(step, template=x)
     806             :       !CALL dbcsr_hadamard_product(prec,grad,step)
     807             :       !CALL dbcsr_scale(step,-1.0_dp)
     808             : 
     809           0 :       CALL dbcsr_create(n, template=x)
     810           0 :       CALL dbcsr_create(m, template=x)
     811           0 :       CALL dbcsr_create(oo1, template=pp)
     812           0 :       CALL dbcsr_create(oo2, template=pp)
     813           0 :       CALL dbcsr_create(res_trial, template=res)
     814           0 :       CALL dbcsr_create(vv_step, template=res)
     815           0 :       CALL dbcsr_create(step_oo, template=res)
     816             : 
     817             :       ! start conjugate gradient iterations
     818           0 :       iteration = 0
     819           0 :       converged = .FALSE.
     820           0 :       prepare_to_exit = .FALSE.
     821           0 :       beta = 0.0_dp
     822           0 :       best_step_size = 0.0_dp
     823           0 :       best_norm = 1.0E+100_dp
     824             :       !ecorr=0.0_dp
     825             :       !change_ecorr=0.0_dp
     826           0 :       restart_conjugator = .FALSE.
     827           0 :       update_prec_freq = 20
     828             :       DO
     829             : 
     830             :          ! (re)-compute the residuals
     831           0 :          IF (iteration .EQ. 0) THEN
     832           0 :             CALL dbcsr_copy(res, qp)
     833           0 :             IF (present_oo) THEN
     834             :                CALL dbcsr_multiply("N", "N", +1.0_dp, qq, x, 0.0_dp, res_trial, &
     835           0 :                                    filter_eps=eps_filter)
     836             :                CALL dbcsr_multiply("N", "N", +1.0_dp, res_trial, oo, 1.0_dp, res, &
     837           0 :                                    filter_eps=eps_filter)
     838             :             ELSE
     839             :                CALL dbcsr_multiply("N", "N", +1.0_dp, qq, x, 1.0_dp, res, &
     840           0 :                                    filter_eps=eps_filter)
     841             :             END IF
     842           0 :             IF (present_vv) THEN
     843             :                CALL dbcsr_multiply("N", "N", -1.0_dp, x, pp, 0.0_dp, res_trial, &
     844           0 :                                    filter_eps=eps_filter)
     845             :                CALL dbcsr_multiply("N", "N", +1.0_dp, vv, res_trial, 1.0_dp, res, &
     846           0 :                                    filter_eps=eps_filter)
     847             :             ELSE
     848             :                CALL dbcsr_multiply("N", "N", -1.0_dp, x, pp, 1.0_dp, res, &
     849           0 :                                    filter_eps=eps_filter)
     850             :             END IF
     851           0 :             IF (quadratic_term) THEN
     852           0 :                IF (present_oo) THEN
     853             :                   CALL dbcsr_multiply("N", "N", +1.0_dp, pq, x, 0.0_dp, oo1, &
     854           0 :                                       filter_eps=eps_filter)
     855             :                   CALL dbcsr_multiply("N", "N", +1.0_dp, oo1, oo, 0.0_dp, oo2, &
     856           0 :                                       filter_eps=eps_filter)
     857             :                ELSE
     858             :                   CALL dbcsr_multiply("N", "N", +1.0_dp, pq, x, 0.0_dp, oo2, &
     859           0 :                                       filter_eps=eps_filter)
     860             :                END IF
     861           0 :                IF (present_vv) THEN
     862             :                   CALL dbcsr_multiply("N", "N", -1.0_dp, x, oo2, 0.0_dp, res_trial, &
     863           0 :                                       filter_eps=eps_filter)
     864             :                   CALL dbcsr_multiply("N", "N", +1.0_dp, vv, res_trial, 1.0_dp, res, &
     865           0 :                                       filter_eps=eps_filter)
     866             :                ELSE
     867             :                   CALL dbcsr_multiply("N", "N", -1.0_dp, x, oo2, 1.0_dp, res, &
     868           0 :                                       filter_eps=eps_filter)
     869             :                END IF
     870             :             END IF
     871           0 :             best_norm = dbcsr_maxabs(res)
     872             :          ELSE
     873           0 :             CALL dbcsr_add(res, m, 1.0_dp, best_step_size)
     874           0 :             CALL dbcsr_add(res, n, 1.0_dp, -best_step_size*best_step_size)
     875           0 :             CALL dbcsr_filter(res, eps_filter)
     876             :          END IF
     877             : 
     878             :          ! check convergence and other exit criteria
     879           0 :          converged = (best_norm .LT. eps_convergence)
     880           0 :          IF (converged .OR. (iteration .GE. max_iter)) THEN
     881             :             prepare_to_exit = .TRUE.
     882             :          END IF
     883             : 
     884           0 :          IF (.NOT. prepare_to_exit) THEN
     885             : 
     886             :             ! update aux1=-pp-pq.x.oo and aux2=qq-vv.x.pq
     887           0 :             IF (quadratic_term) THEN
     888           0 :                IF (iteration .EQ. 0) THEN
     889           0 :                   IF (present_oo) THEN
     890             :                      CALL dbcsr_multiply("N", "N", -1.0_dp, pq, x, 0.0_dp, oo1, &
     891           0 :                                          filter_eps=eps_filter)
     892             :                      CALL dbcsr_multiply("N", "N", +1.0_dp, oo1, oo, 1.0_dp, aux1, &
     893           0 :                                          filter_eps=eps_filter)
     894             :                   ELSE
     895             :                      CALL dbcsr_multiply("N", "N", -1.0_dp, pq, x, 1.0_dp, aux1, &
     896           0 :                                          filter_eps=eps_filter)
     897             :                   END IF
     898           0 :                   IF (present_vv) THEN
     899             :                      CALL dbcsr_multiply("N", "N", -1.0_dp, vv, x, 0.0_dp, res_trial, &
     900           0 :                                          filter_eps=eps_filter)
     901             :                      CALL dbcsr_multiply("N", "N", +1.0_dp, res_trial, pq, 1.0_dp, aux2, &
     902           0 :                                          filter_eps=eps_filter)
     903             :                   ELSE
     904             :                      CALL dbcsr_multiply("N", "N", -1.0_dp, x, pq, 1.0_dp, aux2, &
     905           0 :                                          filter_eps=eps_filter)
     906             :                   END IF
     907             :                ELSE
     908           0 :                   IF (present_oo) THEN
     909             :                      CALL dbcsr_multiply("N", "N", -best_step_size, pq, step_oo, 1.0_dp, aux1, &
     910           0 :                                          filter_eps=eps_filter)
     911             :                   ELSE
     912             :                      CALL dbcsr_multiply("N", "N", -best_step_size, pq, step, 1.0_dp, aux1, &
     913           0 :                                          filter_eps=eps_filter)
     914             :                   END IF
     915           0 :                   IF (present_vv) THEN
     916             :                      CALL dbcsr_multiply("N", "N", -best_step_size, vv_step, pq, 1.0_dp, aux2, &
     917           0 :                                          filter_eps=eps_filter)
     918             :                   ELSE
     919             :                      CALL dbcsr_multiply("N", "N", -best_step_size, step, pq, 1.0_dp, aux2, &
     920           0 :                                          filter_eps=eps_filter)
     921             :                   END IF
     922             :                END IF
     923             :             END IF
     924             : 
     925             :             ! recompute the gradient, do not update it yet
     926             :             ! use m matrix as a temporary storage
     927             :             ! grad=t(vv).res.t(aux1)+t(aux2).res.t(oo)
     928           0 :             IF (present_vv) THEN
     929             :                CALL dbcsr_multiply("N", "T", 1.0_dp, res, aux1, 0.0_dp, res_trial, &
     930           0 :                                    filter_eps=eps_filter)
     931             :                CALL dbcsr_multiply("T", "N", 1.0_dp, vv, res_trial, 0.0_dp, m, &
     932           0 :                                    filter_eps=eps_filter)
     933             :             ELSE
     934             :                CALL dbcsr_multiply("N", "T", 1.0_dp, res, aux1, 0.0_dp, m, &
     935           0 :                                    filter_eps=eps_filter)
     936             :             END IF
     937           0 :             IF (present_oo) THEN
     938             :                CALL dbcsr_multiply("T", "N", 1.0_dp, aux1, res, 0.0_dp, res_trial, &
     939           0 :                                    filter_eps=eps_filter)
     940             :                CALL dbcsr_multiply("N", "T", 1.0_dp, res_trial, oo, 1.0_dp, m, &
     941           0 :                                    filter_eps=eps_filter)
     942             :             ELSE
     943             :                CALL dbcsr_multiply("T", "N", 1.0_dp, aux2, res, 1.0_dp, m, &
     944           0 :                                    filter_eps=eps_filter)
     945             :             END IF
     946             : 
     947             :             ! compute preconditioner
     948             :             !IF (iteration.eq.0.OR.(mod(iteration,update_prec_freq).eq.0)) THEN
     949           0 :             IF (iteration .EQ. 0) THEN
     950           0 :                CALL create_preconditioner(prec, aux1, aux2, eps_filter)
     951             :                !restart_conjugator=.TRUE.
     952             : !CALL dbcsr_set(prec,1.0_dp)
     953             : !CALL dbcsr_print(prec)
     954             :             END IF
     955             : 
     956             :             ! compute the conjugation coefficient - beta
     957           0 :             IF ((iteration .EQ. 0) .OR. restart_conjugator) THEN
     958           0 :                beta = 0.0_dp
     959             :             ELSE
     960           0 :                restart_conjugator = .FALSE.
     961           0 :                SELECT CASE (conjugator)
     962             :                CASE (cg_hestenes_stiefel)
     963           0 :                   CALL dbcsr_add(grad, m, -1.0_dp, 1.0_dp)
     964           0 :                   CALL dbcsr_hadamard_product(prec, grad, n)
     965           0 :                   CALL dbcsr_dot(n, m, numer)
     966           0 :                   CALL dbcsr_dot(grad, step, denom)
     967           0 :                   beta = numer/denom
     968             :                CASE (cg_fletcher_reeves)
     969           0 :                   CALL dbcsr_hadamard_product(prec, grad, n)
     970           0 :                   CALL dbcsr_dot(grad, n, denom)
     971           0 :                   CALL dbcsr_hadamard_product(prec, m, n)
     972           0 :                   CALL dbcsr_dot(m, n, numer)
     973           0 :                   beta = numer/denom
     974             :                CASE (cg_polak_ribiere)
     975           0 :                   CALL dbcsr_hadamard_product(prec, grad, n)
     976           0 :                   CALL dbcsr_dot(grad, n, denom)
     977           0 :                   CALL dbcsr_add(grad, m, -1.0_dp, 1.0_dp)
     978           0 :                   CALL dbcsr_hadamard_product(prec, grad, n)
     979           0 :                   CALL dbcsr_dot(n, m, numer)
     980           0 :                   beta = numer/denom
     981             :                CASE (cg_fletcher)
     982           0 :                   CALL dbcsr_hadamard_product(prec, m, n)
     983           0 :                   CALL dbcsr_dot(m, n, numer)
     984           0 :                   CALL dbcsr_dot(grad, step, denom)
     985           0 :                   beta = -1.0_dp*numer/denom
     986             :                CASE (cg_liu_storey)
     987           0 :                   CALL dbcsr_dot(grad, step, denom)
     988           0 :                   CALL dbcsr_add(grad, m, -1.0_dp, 1.0_dp)
     989           0 :                   CALL dbcsr_hadamard_product(prec, grad, n)
     990           0 :                   CALL dbcsr_dot(n, m, numer)
     991           0 :                   beta = -1.0_dp*numer/denom
     992             :                CASE (cg_dai_yuan)
     993           0 :                   CALL dbcsr_hadamard_product(prec, m, n)
     994           0 :                   CALL dbcsr_dot(m, n, numer)
     995           0 :                   CALL dbcsr_add(grad, m, -1.0_dp, 1.0_dp)
     996           0 :                   CALL dbcsr_dot(grad, step, denom)
     997           0 :                   beta = numer/denom
     998             :                CASE (cg_hager_zhang)
     999           0 :                   CALL dbcsr_add(grad, m, -1.0_dp, 1.0_dp)
    1000           0 :                   CALL dbcsr_dot(grad, step, denom)
    1001           0 :                   CALL dbcsr_hadamard_product(prec, grad, n)
    1002           0 :                   CALL dbcsr_dot(n, grad, numer)
    1003           0 :                   kappa = 2.0_dp*numer/denom
    1004           0 :                   CALL dbcsr_dot(n, m, numer)
    1005           0 :                   tau = numer/denom
    1006           0 :                   CALL dbcsr_dot(step, m, numer)
    1007           0 :                   beta = tau - kappa*numer/denom
    1008             :                CASE (cg_zero)
    1009           0 :                   beta = 0.0_dp
    1010             :                CASE DEFAULT
    1011           0 :                   CPABORT("illegal conjugator")
    1012             :                END SELECT
    1013             :             END IF ! iteration.eq.0
    1014             : 
    1015             :             ! move the current gradient to its storage
    1016           0 :             CALL dbcsr_copy(grad, m)
    1017             : 
    1018             :             ! precondition new gradient (use m as tmp storage)
    1019           0 :             CALL dbcsr_hadamard_product(prec, grad, m)
    1020           0 :             CALL dbcsr_filter(m, eps_filter)
    1021             : 
    1022             :             ! recompute the step direction
    1023           0 :             CALL dbcsr_add(step, m, beta, -1.0_dp)
    1024           0 :             CALL dbcsr_filter(step, eps_filter)
    1025             : 
    1026             : !! ALTERNATIVE METHOD TO OBTAIN THE STEP FROM THE GRADIENT
    1027             : !CALL dbcsr_init(qqqq)
    1028             : !CALL dbcsr_create(qqqq,template=qq)
    1029             : !CALL dbcsr_init(pppp)
    1030             : !CALL dbcsr_create(pppp,template=pp)
    1031             : !CALL dbcsr_init(zero_pq)
    1032             : !CALL dbcsr_create(zero_pq,template=pq)
    1033             : !CALL dbcsr_init(zero_qp)
    1034             : !CALL dbcsr_create(zero_qp,template=qp)
    1035             : !CALL dbcsr_multiply("T","N",1.0_dp,aux2,aux2,0.0_dp,qqqq,&
    1036             : !        filter_eps=eps_filter)
    1037             : !CALL dbcsr_multiply("N","T",-1.0_dp,aux1,aux1,0.0_dp,pppp,&
    1038             : !        filter_eps=eps_filter)
    1039             : !CALL dbcsr_set(zero_qp,0.0_dp)
    1040             : !CALL dbcsr_set(zero_pq,0.0_dp)
    1041             : !CALL solve_riccati_equation(pppp,qqqq,grad,zero_pq,zero_qp,zero_qp,&
    1042             : !               .TRUE.,tensor_type,&
    1043             : !               conjugator,max_iter,eps_convergence,eps_filter,&
    1044             : !               converged,level+1)
    1045             : !CALL dbcsr_release(qqqq)
    1046             : !CALL dbcsr_release(pppp)
    1047             : !CALL dbcsr_release(zero_qp)
    1048             : !CALL dbcsr_release(zero_pq)
    1049             : 
    1050             :             ! calculate the optimal step size
    1051             :             ! m=step.aux1+aux2.step
    1052           0 :             IF (present_vv) THEN
    1053             :                CALL dbcsr_multiply("N", "N", 1.0_dp, vv, step, 0.0_dp, vv_step, &
    1054           0 :                                    filter_eps=eps_filter)
    1055             :                CALL dbcsr_multiply("N", "N", 1.0_dp, vv_step, aux1, 0.0_dp, m, &
    1056           0 :                                    filter_eps=eps_filter)
    1057             :             ELSE
    1058             :                CALL dbcsr_multiply("N", "N", 1.0_dp, step, aux1, 0.0_dp, m, &
    1059           0 :                                    filter_eps=eps_filter)
    1060             :             END IF
    1061           0 :             IF (present_oo) THEN
    1062             :                CALL dbcsr_multiply("N", "N", 1.0_dp, step, oo, 0.0_dp, step_oo, &
    1063           0 :                                    filter_eps=eps_filter)
    1064             :                CALL dbcsr_multiply("N", "N", 1.0_dp, aux2, step_oo, 1.0_dp, m, &
    1065           0 :                                    filter_eps=eps_filter)
    1066             :             ELSE
    1067             :                CALL dbcsr_multiply("N", "N", 1.0_dp, aux2, step, 1.0_dp, m, &
    1068           0 :                                    filter_eps=eps_filter)
    1069             :             END IF
    1070             : 
    1071           0 :             IF (quadratic_term) THEN
    1072             :                ! n=step.pq.step
    1073           0 :                IF (present_oo) THEN
    1074             :                   CALL dbcsr_multiply("N", "N", 1.0_dp, pq, step, 0.0_dp, oo1, &
    1075           0 :                                       filter_eps=eps_filter)
    1076             :                   CALL dbcsr_multiply("N", "N", 1.0_dp, oo1, oo, 0.0_dp, oo2, &
    1077           0 :                                       filter_eps=eps_filter)
    1078             :                ELSE
    1079             :                   CALL dbcsr_multiply("N", "N", 1.0_dp, pq, step, 0.0_dp, oo2, &
    1080           0 :                                       filter_eps=eps_filter)
    1081             :                END IF
    1082           0 :                IF (present_vv) THEN
    1083             :                   CALL dbcsr_multiply("N", "N", 1.0_dp, step, oo2, 0.0_dp, res_trial, &
    1084           0 :                                       filter_eps=eps_filter)
    1085             :                   CALL dbcsr_multiply("N", "N", 1.0_dp, vv, res_trial, 0.0_dp, n, &
    1086           0 :                                       filter_eps=eps_filter)
    1087             :                ELSE
    1088             :                   CALL dbcsr_multiply("N", "N", 1.0_dp, step, oo2, 0.0_dp, n, &
    1089           0 :                                       filter_eps=eps_filter)
    1090             :                END IF
    1091             : 
    1092             :             ELSE
    1093           0 :                CALL dbcsr_set(n, 0.0_dp)
    1094             :             END IF
    1095             : 
    1096             :             ! calculate coefficients of the cubic eq for alpha - step size
    1097           0 :             c0 = 2.0_dp*(dbcsr_frobenius_norm(n))**2
    1098             : 
    1099           0 :             CALL dbcsr_dot(m, n, c1)
    1100           0 :             c1 = -3.0_dp*c1
    1101             : 
    1102           0 :             CALL dbcsr_dot(res, n, c2)
    1103           0 :             c2 = -2.0_dp*c2 + (dbcsr_frobenius_norm(m))**2
    1104             : 
    1105           0 :             CALL dbcsr_dot(res, m, c3)
    1106             : 
    1107             :             ! find step size
    1108           0 :             CALL analytic_line_search(c0, c1, c2, c3, step_size, nsteps)
    1109             : 
    1110           0 :             IF (nsteps .EQ. 0) THEN
    1111           0 :                CPABORT("no step sizes!")
    1112             :             END IF
    1113             :             ! if we have several possible step sizes
    1114             :             ! choose one with the lowest objective function
    1115           0 :             best_norm = 1.0E+100_dp
    1116           0 :             best_step_size = 0.0_dp
    1117           0 :             DO istep = 1, nsteps
    1118             :                ! recompute the residues
    1119           0 :                CALL dbcsr_copy(res_trial, res)
    1120           0 :                CALL dbcsr_add(res_trial, m, 1.0_dp, step_size(istep))
    1121           0 :                CALL dbcsr_add(res_trial, n, 1.0_dp, -step_size(istep)*step_size(istep))
    1122           0 :                CALL dbcsr_filter(res_trial, eps_filter)
    1123             :                ! RZK-warning objective function might be different in the case of
    1124             :                ! tensor_up_down
    1125             :                !obj_function=0.5_dp*(dbcsr_frobenius_norm(res_trial))**2
    1126           0 :                obj_function = dbcsr_maxabs(res_trial)
    1127           0 :                IF (obj_function .LT. best_norm) THEN
    1128           0 :                   best_norm = obj_function
    1129           0 :                   best_step_size = step_size(istep)
    1130             :                END IF
    1131             :             END DO
    1132             : 
    1133             :          END IF
    1134             : 
    1135             :          ! update X along the line
    1136           0 :          CALL dbcsr_add(x, step, 1.0_dp, best_step_size)
    1137           0 :          CALL dbcsr_filter(x, eps_filter)
    1138             : 
    1139             :          ! evaluate current energy correction
    1140             :          !change_ecorr=ecorr
    1141             :          !CALL dbcsr_dot(qp,x,ecorr,"T","N")
    1142             :          !change_ecorr=ecorr-change_ecorr
    1143             : 
    1144             :          ! check convergence and other exit criteria
    1145           0 :          converged = (best_norm .LT. eps_convergence)
    1146           0 :          IF (converged .OR. (iteration .GE. max_iter)) THEN
    1147           0 :             prepare_to_exit = .TRUE.
    1148             :          END IF
    1149             : 
    1150           0 :          t2 = m_walltime()
    1151             : 
    1152           0 :          IF (unit_nr > 0) THEN
    1153             :             WRITE (unit_nr, '(T6,A,1X,I4,1X,E12.3,F8.3)') &
    1154           0 :                "RICCATI iter ", iteration, best_norm, t2 - t1
    1155             :             !WRITE(unit_nr,'(T6,A,1X,I4,1X,F15.9,F15.9,E12.3,F8.3)') &
    1156             :             !   "RICCATI iter ",iteration,ecorr,change_ecorr,best_norm,t2-t1
    1157             :          END IF
    1158             : 
    1159           0 :          t1 = m_walltime()
    1160             : 
    1161           0 :          iteration = iteration + 1
    1162             : 
    1163           0 :          IF (prepare_to_exit) EXIT
    1164             : 
    1165             :       END DO
    1166             : 
    1167           0 :       CALL dbcsr_release(aux1)
    1168           0 :       CALL dbcsr_release(aux2)
    1169           0 :       CALL dbcsr_release(grad)
    1170           0 :       CALL dbcsr_release(step)
    1171           0 :       CALL dbcsr_release(n)
    1172           0 :       CALL dbcsr_release(m)
    1173           0 :       CALL dbcsr_release(oo1)
    1174           0 :       CALL dbcsr_release(oo2)
    1175           0 :       CALL dbcsr_release(res_trial)
    1176           0 :       CALL dbcsr_release(vv_step)
    1177           0 :       CALL dbcsr_release(step_oo)
    1178             : 
    1179           0 :       CALL timestop(handle)
    1180             : 
    1181           0 :    END SUBROUTINE solve_riccati_equation
    1182             : 
    1183             : ! **************************************************************************************************
    1184             : !> \brief Computes a preconditioner from diagonal elements of ~f_oo, ~f_vv
    1185             : !>        The preconditioner is approximately equal to
    1186             : !>        prec_ai ~ (e_a - e_i)^(-2)
    1187             : !>        However, the real expression is more complex
    1188             : !> \param prec ...
    1189             : !> \param pp ...
    1190             : !> \param qq ...
    1191             : !> \param eps_filter ...
    1192             : !> \par History
    1193             : !>       2011.07 created [Rustam Z Khaliullin]
    1194             : !> \author Rustam Z Khaliullin
    1195             : ! **************************************************************************************************
    1196           0 :    SUBROUTINE create_preconditioner(prec, pp, qq, eps_filter)
    1197             : 
    1198             :       TYPE(dbcsr_type), INTENT(OUT)                      :: prec
    1199             :       TYPE(dbcsr_type), INTENT(IN)                       :: pp, qq
    1200             :       REAL(KIND=dp), INTENT(IN)                          :: eps_filter
    1201             : 
    1202             :       CHARACTER(len=*), PARAMETER :: routineN = 'create_preconditioner'
    1203             : 
    1204             :       INTEGER                                            :: handle, p_nrows, q_nrows
    1205           0 :       REAL(KIND=dp), ALLOCATABLE, DIMENSION(:)           :: p_diagonal, q_diagonal
    1206           0 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: block
    1207             :       TYPE(dbcsr_iterator_type)                          :: iter
    1208             :       TYPE(dbcsr_type)                                   :: pp_diag, qq_diag, t1, t2, tmp
    1209             : 
    1210             : !LOGICAL, INTENT(IN)                      :: use_virt_orbs
    1211             : 
    1212           0 :       CALL timeset(routineN, handle)
    1213             : 
    1214             : !    ! copy diagonal elements
    1215             : !    CALL dbcsr_get_info(pp,nfullrows_total=nrows)
    1216             : !    CALL dbcsr_init(pp_diag)
    1217             : !    CALL dbcsr_create(pp_diag,template=pp)
    1218             : !    ALLOCATE(diagonal(nrows))
    1219             : !    CALL dbcsr_get_diag(pp,diagonal)
    1220             : !    CALL dbcsr_add_on_diag(pp_diag,1.0_dp)
    1221             : !    CALL dbcsr_set_diag(pp_diag,diagonal)
    1222             : !    DEALLOCATE(diagonal)
    1223             : !
    1224             :       ! initialize a matrix to 1.0
    1225           0 :       CALL dbcsr_create(tmp, template=prec)
    1226           0 :       CALL dbcsr_reserve_diag_blocks(tmp)
    1227           0 :       CALL dbcsr_iterator_start(iter, tmp)
    1228           0 :       DO WHILE (dbcsr_iterator_blocks_left(iter))
    1229           0 :          CALL dbcsr_iterator_next_block(iter, block=block)
    1230           0 :          block(:, :) = 1.0_dp
    1231             :       END DO
    1232           0 :       CALL dbcsr_iterator_stop(iter)
    1233             : 
    1234             :       ! copy diagonal elements of pp into cols of a matrix
    1235           0 :       CALL dbcsr_get_info(pp, nfullrows_total=p_nrows)
    1236           0 :       CALL dbcsr_create(pp_diag, template=pp)
    1237           0 :       ALLOCATE (p_diagonal(p_nrows))
    1238           0 :       CALL dbcsr_get_diag(pp, p_diagonal)
    1239           0 :       CALL dbcsr_add_on_diag(pp_diag, 1.0_dp)
    1240           0 :       CALL dbcsr_set_diag(pp_diag, p_diagonal)
    1241             :       ! RZK-warning is it possible to use dbcsr_scale_by_vector?
    1242             :       ! or even insert elements directly in the prev cycles
    1243           0 :       CALL dbcsr_create(t2, template=prec)
    1244             :       CALL dbcsr_multiply("N", "N", 1.0_dp, tmp, pp_diag, &
    1245           0 :                           0.0_dp, t2, filter_eps=eps_filter)
    1246             : 
    1247             :       ! copy diagonal elements qq into rows of a matrix
    1248           0 :       CALL dbcsr_get_info(qq, nfullrows_total=q_nrows)
    1249           0 :       CALL dbcsr_create(qq_diag, template=qq)
    1250           0 :       ALLOCATE (q_diagonal(q_nrows))
    1251           0 :       CALL dbcsr_get_diag(qq, q_diagonal)
    1252           0 :       CALL dbcsr_add_on_diag(qq_diag, 1.0_dp)
    1253           0 :       CALL dbcsr_set_diag(qq_diag, q_diagonal)
    1254           0 :       CALL dbcsr_set(tmp, 1.0_dp)
    1255           0 :       CALL dbcsr_create(t1, template=prec)
    1256             :       CALL dbcsr_multiply("N", "N", 1.0_dp, qq_diag, tmp, &
    1257           0 :                           0.0_dp, t1, filter_eps=eps_filter)
    1258             : 
    1259           0 :       CALL dbcsr_hadamard_product(t1, t2, prec)
    1260           0 :       CALL dbcsr_release(t1)
    1261           0 :       CALL dbcsr_scale(prec, 2.0_dp)
    1262             : 
    1263             :       ! Get the diagonal of tr(qq).qq
    1264             :       CALL dbcsr_multiply("T", "N", 1.0_dp, qq, qq, &
    1265             :                           0.0_dp, qq_diag, retain_sparsity=.TRUE., &
    1266           0 :                           filter_eps=eps_filter)
    1267           0 :       CALL dbcsr_get_diag(qq_diag, q_diagonal)
    1268           0 :       CALL dbcsr_set(qq_diag, 0.0_dp)
    1269           0 :       CALL dbcsr_add_on_diag(qq_diag, 1.0_dp)
    1270           0 :       CALL dbcsr_set_diag(qq_diag, q_diagonal)
    1271           0 :       DEALLOCATE (q_diagonal)
    1272           0 :       CALL dbcsr_set(tmp, 1.0_dp)
    1273             :       CALL dbcsr_multiply("N", "N", 1.0_dp, qq_diag, tmp, &
    1274           0 :                           0.0_dp, t2, filter_eps=eps_filter)
    1275           0 :       CALL dbcsr_release(qq_diag)
    1276           0 :       CALL dbcsr_add(prec, t2, 1.0_dp, 1.0_dp)
    1277             : 
    1278             :       ! Get the diagonal of pp.tr(pp)
    1279             :       CALL dbcsr_multiply("N", "T", 1.0_dp, pp, pp, &
    1280             :                           0.0_dp, pp_diag, retain_sparsity=.TRUE., &
    1281           0 :                           filter_eps=eps_filter)
    1282           0 :       CALL dbcsr_get_diag(pp_diag, p_diagonal)
    1283           0 :       CALL dbcsr_set(pp_diag, 0.0_dp)
    1284           0 :       CALL dbcsr_add_on_diag(pp_diag, 1.0_dp)
    1285           0 :       CALL dbcsr_set_diag(pp_diag, p_diagonal)
    1286           0 :       DEALLOCATE (p_diagonal)
    1287           0 :       CALL dbcsr_set(tmp, 1.0_dp)
    1288             :       CALL dbcsr_multiply("N", "N", 1.0_dp, tmp, pp_diag, &
    1289           0 :                           0.0_dp, t2, filter_eps=eps_filter)
    1290           0 :       CALL dbcsr_release(tmp)
    1291           0 :       CALL dbcsr_release(pp_diag)
    1292           0 :       CALL dbcsr_add(prec, t2, 1.0_dp, 1.0_dp)
    1293             : 
    1294             :       ! now add the residual component
    1295             :       !CALL dbcsr_hadamard_product(res,qp,t2)
    1296             :       !CALL dbcsr_add(prec,t2,1.0_dp,-2.0_dp)
    1297           0 :       CALL dbcsr_release(t2)
    1298           0 :       CALL inverse_of_elements(prec)
    1299           0 :       CALL dbcsr_filter(prec, eps_filter)
    1300             : 
    1301           0 :       CALL timestop(handle)
    1302             : 
    1303           0 :    END SUBROUTINE create_preconditioner
    1304             : 
    1305             : ! **************************************************************************************************
    1306             : !> \brief Computes 1/x of the matrix elements.
    1307             : !> \param matrix ...
    1308             : !> \author Ole Schuett
    1309             : ! **************************************************************************************************
    1310           0 :    SUBROUTINE inverse_of_elements(matrix)
    1311             :       TYPE(dbcsr_type), INTENT(INOUT)                    :: matrix
    1312             : 
    1313             :       CHARACTER(len=*), PARAMETER :: routineN = 'inverse_of_elements'
    1314             : 
    1315             :       INTEGER                                            :: handle
    1316           0 :       REAL(kind=dp), DIMENSION(:, :), POINTER            :: block
    1317             :       TYPE(dbcsr_iterator_type)                          :: iter
    1318             : 
    1319           0 :       CALL timeset(routineN, handle)
    1320           0 :       CALL dbcsr_iterator_start(iter, matrix)
    1321           0 :       DO WHILE (dbcsr_iterator_blocks_left(iter))
    1322           0 :          CALL dbcsr_iterator_next_block(iter, block=block)
    1323           0 :          block = 1.0_dp/block
    1324             :       END DO
    1325           0 :       CALL dbcsr_iterator_stop(iter)
    1326           0 :       CALL timestop(handle)
    1327             : 
    1328           0 :    END SUBROUTINE inverse_of_elements
    1329             : 
    1330             : ! **************************************************************************************************
    1331             : !> \brief Finds real roots of a cubic equation
    1332             : !>    >        a*x**3 + b*x**2 + c*x + d = 0
    1333             : !>        and returns only those roots for which the derivative is positive
    1334             : !>
    1335             : !>   Step 0: Check the true order of the equation. Cubic, quadratic, linear?
    1336             : !>   Step 1: Calculate p and q
    1337             : !>           p = ( 3*c/a - (b/a)**2 ) / 3
    1338             : !>           q = ( 2*(b/a)**3 - 9*b*c/a/a + 27*d/a ) / 27
    1339             : !>   Step 2: Calculate discriminant D
    1340             : !>           D = (p/3)**3 + (q/2)**2
    1341             : !>   Step 3: Depending on the sign of D, we follow different strategy.
    1342             : !>           If D<0, three distinct real roots.
    1343             : !>           If D=0, three real roots of which at least two are equal.
    1344             : !>           If D>0, one real and two complex roots.
    1345             : !>   Step 3a: For D>0 and D=0,
    1346             : !>           Calculate u and v
    1347             : !>           u = cubic_root(-q/2 + sqrt(D))
    1348             : !>           v = cubic_root(-q/2 - sqrt(D))
    1349             : !>           Find the three transformed roots
    1350             : !>           y1 = u + v
    1351             : !>           y2 = -(u+v)/2 + i (u-v)*sqrt(3)/2
    1352             : !>           y3 = -(u+v)/2 - i (u-v)*sqrt(3)/2
    1353             : !>   Step 3b Alternately, for D<0, a trigonometric formulation is more convenient
    1354             : !>           y1 =  2 * sqrt(|p|/3) * cos(phi/3)
    1355             : !>           y2 = -2 * sqrt(|p|/3) * cos((phi+pi)/3)
    1356             : !>           y3 = -2 * sqrt(|p|/3) * cos((phi-pi)/3)
    1357             : !>           where phi = acos(-q/2/sqrt(|p|**3/27))
    1358             : !>                 pi  = 3.141592654...
    1359             : !>   Step 4  Find the real roots
    1360             : !>           x = y - b/a/3
    1361             : !>   Step 5  Check the derivative and return only those real roots
    1362             : !>           for which the derivative is positive
    1363             : !>
    1364             : !> \param a ...
    1365             : !> \param b ...
    1366             : !> \param c ...
    1367             : !> \param d ...
    1368             : !> \param minima ...
    1369             : !> \param nmins ...
    1370             : !> \par History
    1371             : !>       2011.06 created [Rustam Z Khaliullin]
    1372             : !> \author Rustam Z Khaliullin
    1373             : ! **************************************************************************************************
    1374           0 :    SUBROUTINE analytic_line_search(a, b, c, d, minima, nmins)
    1375             : 
    1376             :       REAL(KIND=dp), INTENT(IN)                          :: a, b, c, d
    1377             :       REAL(KIND=dp), DIMENSION(3), INTENT(OUT)           :: minima
    1378             :       INTEGER, INTENT(OUT)                               :: nmins
    1379             : 
    1380             :       INTEGER                                            :: i, nroots
    1381             :       REAL(KIND=dp)                                      :: DD, der, p, phi, pi, q, temp1, temp2, u, &
    1382             :                                                             v, y1, y2, y2i, y2r, y3
    1383             :       REAL(KIND=dp), DIMENSION(3)                        :: x
    1384             : 
    1385             : !    CALL timeset(routineN,handle)
    1386             : 
    1387           0 :       pi = ACOS(-1.0_dp)
    1388             : 
    1389             :       ! Step 0: Check coefficients and find the true order of the eq
    1390           0 :       IF (a .EQ. 0.0_dp) THEN
    1391           0 :          IF (b .EQ. 0.0_dp) THEN
    1392           0 :             IF (c .EQ. 0.0_dp) THEN
    1393             :                ! Non-equation, no valid solutions
    1394             :                nroots = 0
    1395             :             ELSE
    1396             :                ! Linear equation with one root.
    1397           0 :                nroots = 1
    1398           0 :                x(1) = -d/c
    1399             :             END IF
    1400             :          ELSE
    1401             :             ! Quadratic equation with max two roots.
    1402           0 :             DD = c*c - 4.0_dp*b*d
    1403           0 :             IF (DD .GT. 0.0_dp) THEN
    1404           0 :                nroots = 2
    1405           0 :                x(1) = (-c + SQRT(DD))/2.0_dp/b
    1406           0 :                x(2) = (-c - SQRT(DD))/2.0_dp/b
    1407           0 :             ELSE IF (DD .LT. 0.0_dp) THEN
    1408             :                nroots = 0
    1409             :             ELSE
    1410           0 :                nroots = 1
    1411           0 :                x(1) = -c/2.0_dp/b
    1412             :             END IF
    1413             :          END IF
    1414             :       ELSE
    1415             :          ! Cubic equation with max three roots
    1416             :          ! Calculate p and q
    1417           0 :          p = c/a - b*b/a/a/3.0_dp
    1418           0 :          q = (2.0_dp*b*b*b/a/a/a - 9.0_dp*b*c/a/a + 27.0_dp*d/a)/27.0_dp
    1419             : 
    1420             :          ! Calculate DD
    1421           0 :          DD = p*p*p/27.0_dp + q*q/4.0_dp
    1422             : 
    1423           0 :          IF (DD .LT. 0.0_dp) THEN
    1424             :             ! three real unequal roots -- use the trigonometric formulation
    1425           0 :             phi = ACOS(-q/2.0_dp/SQRT(ABS(p*p*p)/27.0_dp))
    1426           0 :             temp1 = 2.0_dp*SQRT(ABS(p)/3.0_dp)
    1427           0 :             y1 = temp1*COS(phi/3.0_dp)
    1428           0 :             y2 = -temp1*COS((phi + pi)/3.0_dp)
    1429           0 :             y3 = -temp1*COS((phi - pi)/3.0_dp)
    1430             :          ELSE
    1431             :             ! 1 real & 2 conjugate complex roots OR 3 real roots (some are equal)
    1432           0 :             temp1 = -q/2.0_dp + SQRT(DD)
    1433           0 :             temp2 = -q/2.0_dp - SQRT(DD)
    1434           0 :             u = ABS(temp1)**(1.0_dp/3.0_dp)
    1435           0 :             v = ABS(temp2)**(1.0_dp/3.0_dp)
    1436           0 :             IF (temp1 .LT. 0.0_dp) u = -u
    1437           0 :             IF (temp2 .LT. 0.0_dp) v = -v
    1438           0 :             y1 = u + v
    1439           0 :             y2r = -(u + v)/2.0_dp
    1440           0 :             y2i = (u - v)*SQRT(3.0_dp)/2.0_dp
    1441             :          END IF
    1442             : 
    1443             :          ! Final transformation
    1444           0 :          temp1 = b/a/3.0_dp
    1445           0 :          y1 = y1 - temp1
    1446           0 :          y2 = y2 - temp1
    1447           0 :          y3 = y3 - temp1
    1448           0 :          y2r = y2r - temp1
    1449             : 
    1450             :          ! Assign answers
    1451           0 :          IF (DD .LT. 0.0_dp) THEN
    1452           0 :             nroots = 3
    1453           0 :             x(1) = y1
    1454           0 :             x(2) = y2
    1455           0 :             x(3) = y3
    1456           0 :          ELSE IF (DD .EQ. 0.0_dp) THEN
    1457           0 :             nroots = 2
    1458           0 :             x(1) = y1
    1459           0 :             x(2) = y2r
    1460             :             !x(3) = cmplx(y2r,  0.)
    1461             :          ELSE
    1462           0 :             nroots = 1
    1463           0 :             x(1) = y1
    1464             :             !x(2) = cmplx(y2r, y2i)
    1465             :             !x(3) = cmplx(y2r,-y2i)
    1466             :          END IF
    1467             : 
    1468             :       END IF
    1469             : 
    1470             : !write(*,'(i2,a)') nroots, ' real root(s)'
    1471           0 :       nmins = 0
    1472           0 :       DO i = 1, nroots
    1473             :          ! maximum or minimum? use the derivative
    1474             :          ! 3*a*x**2+2*b*x+c
    1475           0 :          der = 3.0_dp*a*x(i)*x(i) + 2.0_dp*b*x(i) + c
    1476           0 :          IF (der .GT. 0.0_dp) THEN
    1477           0 :             nmins = nmins + 1
    1478           0 :             minima(nmins) = x(i)
    1479             : !write(*,'(a,i2,a,f10.5)') 'Minimum ', i, ', value: ', x(i)
    1480             :          END IF
    1481             :       END DO
    1482             : 
    1483             : !    CALL timestop(handle)
    1484             : 
    1485           0 :    END SUBROUTINE analytic_line_search
    1486             : 
    1487             : ! **************************************************************************************************
    1488             : !> \brief Diagonalizes diagonal blocks of a symmetric dbcsr matrix
    1489             : !>        and returs its eigenvectors
    1490             : !> \param matrix ...
    1491             : !> \param c ...
    1492             : !> \param e ...
    1493             : !> \par History
    1494             : !>       2011.07 created [Rustam Z Khaliullin]
    1495             : !> \author Rustam Z Khaliullin
    1496             : ! **************************************************************************************************
    1497           0 :    SUBROUTINE diagonalize_diagonal_blocks(matrix, c, e)
    1498             : 
    1499             :       TYPE(dbcsr_type), INTENT(IN)                       :: matrix
    1500             :       TYPE(dbcsr_type), INTENT(OUT)                      :: c
    1501             :       TYPE(dbcsr_type), INTENT(OUT), OPTIONAL            :: e
    1502             : 
    1503             :       CHARACTER(len=*), PARAMETER :: routineN = 'diagonalize_diagonal_blocks'
    1504             : 
    1505             :       INTEGER                                            :: handle, iblock_col, iblock_row, &
    1506             :                                                             iblock_size, info, lwork, orbital
    1507             :       LOGICAL                                            :: block_needed, do_eigenvalues
    1508           0 :       REAL(kind=dp), ALLOCATABLE, DIMENSION(:)           :: eigenvalues, work
    1509           0 :       REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :)        :: data_copy, new_block
    1510           0 :       REAL(kind=dp), DIMENSION(:, :), POINTER            :: data_p
    1511             :       TYPE(dbcsr_iterator_type)                          :: iter
    1512             : 
    1513           0 :       CALL timeset(routineN, handle)
    1514             : 
    1515           0 :       IF (PRESENT(e)) THEN
    1516             :          do_eigenvalues = .TRUE.
    1517             :       ELSE
    1518           0 :          do_eigenvalues = .FALSE.
    1519             :       END IF
    1520             : 
    1521             :       ! create a matrix for eigenvectors
    1522           0 :       CALL dbcsr_work_create(c, work_mutable=.TRUE.)
    1523           0 :       IF (do_eigenvalues) &
    1524           0 :          CALL dbcsr_work_create(e, work_mutable=.TRUE.)
    1525             : 
    1526           0 :       CALL dbcsr_iterator_readonly_start(iter, matrix)
    1527             : 
    1528           0 :       DO WHILE (dbcsr_iterator_blocks_left(iter))
    1529             : 
    1530           0 :          CALL dbcsr_iterator_next_block(iter, iblock_row, iblock_col, data_p, row_size=iblock_size)
    1531             : 
    1532           0 :          block_needed = .FALSE.
    1533           0 :          IF (iblock_row == iblock_col) block_needed = .TRUE.
    1534             : 
    1535           0 :          IF (block_needed) THEN
    1536             : 
    1537             :             ! Prepare data
    1538           0 :             ALLOCATE (eigenvalues(iblock_size))
    1539           0 :             ALLOCATE (data_copy(iblock_size, iblock_size))
    1540           0 :             data_copy(:, :) = data_p(:, :)
    1541             : 
    1542             :             ! Query the optimal workspace for dsyev
    1543           0 :             LWORK = -1
    1544           0 :             ALLOCATE (WORK(MAX(1, LWORK)))
    1545           0 :             CALL dsyev('V', 'L', iblock_size, data_copy, iblock_size, eigenvalues, WORK, LWORK, INFO)
    1546           0 :             LWORK = INT(WORK(1))
    1547           0 :             DEALLOCATE (WORK)
    1548             : 
    1549             :             ! Allocate the workspace and solve the eigenproblem
    1550           0 :             ALLOCATE (WORK(MAX(1, LWORK)))
    1551           0 :             CALL dsyev('V', 'L', iblock_size, data_copy, iblock_size, eigenvalues, WORK, LWORK, INFO)
    1552           0 :             IF (INFO .NE. 0) CPABORT("DSYEV failed")
    1553             : 
    1554             :             ! copy eigenvectors into a cp_dbcsr matrix
    1555           0 :             CALL dbcsr_put_block(c, iblock_row, iblock_col, block=data_copy)
    1556             : 
    1557             :             ! if requested copy eigenvalues into a cp_dbcsr matrix
    1558           0 :             IF (do_eigenvalues) THEN
    1559           0 :                ALLOCATE (new_block(iblock_size, iblock_size))
    1560           0 :                new_block(:, :) = 0.0_dp
    1561           0 :                DO orbital = 1, iblock_size
    1562           0 :                   new_block(orbital, orbital) = eigenvalues(orbital)
    1563             :                END DO
    1564           0 :                CALL dbcsr_put_block(e, iblock_row, iblock_col, new_block)
    1565           0 :                DEALLOCATE (new_block)
    1566             :             END IF
    1567             : 
    1568           0 :             DEALLOCATE (WORK)
    1569           0 :             DEALLOCATE (data_copy)
    1570           0 :             DEALLOCATE (eigenvalues)
    1571             : 
    1572             :          END IF
    1573             : 
    1574             :       END DO
    1575             : 
    1576           0 :       CALL dbcsr_iterator_stop(iter)
    1577             : 
    1578           0 :       CALL dbcsr_finalize(c)
    1579           0 :       IF (do_eigenvalues) CALL dbcsr_finalize(e)
    1580             : 
    1581           0 :       CALL timestop(handle)
    1582             : 
    1583           0 :    END SUBROUTINE diagonalize_diagonal_blocks
    1584             : 
    1585             : ! **************************************************************************************************
    1586             : !> \brief Transforms a matrix M_out = tr(U1) * M_in * U2
    1587             : !> \param matrix ...
    1588             : !> \param u1 ...
    1589             : !> \param u2 ...
    1590             : !> \param eps_filter ...
    1591             : !> \par History
    1592             : !>       2011.10 created [Rustam Z Khaliullin]
    1593             : !> \author Rustam Z Khaliullin
    1594             : ! **************************************************************************************************
    1595           0 :    SUBROUTINE matrix_forward_transform(matrix, u1, u2, eps_filter)
    1596             : 
    1597             :       TYPE(dbcsr_type), INTENT(INOUT)                    :: matrix
    1598             :       TYPE(dbcsr_type), INTENT(IN)                       :: u1, u2
    1599             :       REAL(KIND=dp), INTENT(IN)                          :: eps_filter
    1600             : 
    1601             :       CHARACTER(len=*), PARAMETER :: routineN = 'matrix_forward_transform'
    1602             : 
    1603             :       INTEGER                                            :: handle
    1604             :       TYPE(dbcsr_type)                                   :: tmp
    1605             : 
    1606           0 :       CALL timeset(routineN, handle)
    1607             : 
    1608             :       CALL dbcsr_create(tmp, template=matrix, &
    1609           0 :                         matrix_type=dbcsr_type_no_symmetry)
    1610             :       CALL dbcsr_multiply("N", "N", 1.0_dp, matrix, u2, 0.0_dp, tmp, &
    1611           0 :                           filter_eps=eps_filter)
    1612             :       CALL dbcsr_multiply("T", "N", 1.0_dp, u1, tmp, 0.0_dp, matrix, &
    1613           0 :                           filter_eps=eps_filter)
    1614           0 :       CALL dbcsr_release(tmp)
    1615             : 
    1616           0 :       CALL timestop(handle)
    1617             : 
    1618           0 :    END SUBROUTINE matrix_forward_transform
    1619             : 
    1620             : ! **************************************************************************************************
    1621             : !> \brief Transforms a matrix M_out = U1 * M_in * tr(U2)
    1622             : !> \param matrix ...
    1623             : !> \param u1 ...
    1624             : !> \param u2 ...
    1625             : !> \param eps_filter ...
    1626             : !> \par History
    1627             : !>       2011.10 created [Rustam Z Khaliullin]
    1628             : !> \author Rustam Z Khaliullin
    1629             : ! **************************************************************************************************
    1630           0 :    SUBROUTINE matrix_backward_transform(matrix, u1, u2, eps_filter)
    1631             : 
    1632             :       TYPE(dbcsr_type), INTENT(INOUT)                    :: matrix
    1633             :       TYPE(dbcsr_type), INTENT(IN)                       :: u1, u2
    1634             :       REAL(KIND=dp), INTENT(IN)                          :: eps_filter
    1635             : 
    1636             :       CHARACTER(len=*), PARAMETER :: routineN = 'matrix_backward_transform'
    1637             : 
    1638             :       INTEGER                                            :: handle
    1639             :       TYPE(dbcsr_type)                                   :: tmp
    1640             : 
    1641           0 :       CALL timeset(routineN, handle)
    1642             : 
    1643             :       CALL dbcsr_create(tmp, template=matrix, &
    1644           0 :                         matrix_type=dbcsr_type_no_symmetry)
    1645             :       CALL dbcsr_multiply("N", "T", 1.0_dp, matrix, u2, 0.0_dp, tmp, &
    1646           0 :                           filter_eps=eps_filter)
    1647             :       CALL dbcsr_multiply("N", "N", 1.0_dp, u1, tmp, 0.0_dp, matrix, &
    1648           0 :                           filter_eps=eps_filter)
    1649           0 :       CALL dbcsr_release(tmp)
    1650             : 
    1651           0 :       CALL timestop(handle)
    1652             : 
    1653           0 :    END SUBROUTINE matrix_backward_transform
    1654             : 
    1655             : !! **************************************************************************************************
    1656             : !!> \brief Transforms to a representation in which diagonal blocks
    1657             : !!>        of qq and pp matrices are diagonal. This can improve convergence
    1658             : !!>        of PCG
    1659             : !!> \par History
    1660             : !!>       2011.07 created [Rustam Z Khaliullin]
    1661             : !!> \author Rustam Z Khaliullin
    1662             : !! **************************************************************************************************
    1663             : !  SUBROUTINE transform_matrices_to_blk_diag(matrix_pp,matrix_qq,matrix_qp,&
    1664             : !    matrix_pq,eps_filter)
    1665             : !
    1666             : !    TYPE(dbcsr_type), INTENT(INOUT)       :: matrix_pp, matrix_qq,&
    1667             : !                                                matrix_qp, matrix_pq
    1668             : !    REAL(KIND=dp), INTENT(IN)                :: eps_filter
    1669             : !
    1670             : !    CHARACTER(len=*), PARAMETER :: routineN = 'transform_matrices_to_blk_diag',&
    1671             : !      routineP = moduleN//':'//routineN
    1672             : !
    1673             : !    TYPE(dbcsr_type)                      :: tmp_pp, tmp_qq,&
    1674             : !                                                tmp_qp, tmp_pq,&
    1675             : !                                                blk, blk2
    1676             : !    INTEGER                                  :: handle
    1677             : !
    1678             : !    CALL timeset(routineN,handle)
    1679             : !
    1680             : !    ! find a better basis by diagonalizing diagonal blocks
    1681             : !    ! first pp
    1682             : !    CALL dbcsr_init(blk)
    1683             : !    CALL dbcsr_create(blk,template=matrix_pp)
    1684             : !    CALL diagonalize_diagonal_blocks(matrix_pp,blk)
    1685             : !
    1686             : !    ! convert matrices to the new basis
    1687             : !    CALL dbcsr_init(tmp_pp)
    1688             : !    CALL dbcsr_create(tmp_pp,template=matrix_pp)
    1689             : !    CALL dbcsr_multiply("N","N",1.0_dp,matrix_pp,blk,0.0_dp,tmp_pp,&
    1690             : !               filter_eps=eps_filter)
    1691             : !    CALL dbcsr_multiply("T","N",1.0_dp,blk,tmp_pp,0.0_dp,matrix_pp,&
    1692             : !               filter_eps=eps_filter)
    1693             : !    CALL dbcsr_release(tmp_pp)
    1694             : !
    1695             : !    ! now qq
    1696             : !    CALL dbcsr_init(blk2)
    1697             : !    CALL dbcsr_create(blk2,template=matrix_qq)
    1698             : !    CALL diagonalize_diagonal_blocks(matrix_qq,blk2)
    1699             : !
    1700             : !    CALL dbcsr_init(tmp_qq)
    1701             : !    CALL dbcsr_create(tmp_qq,template=matrix_qq)
    1702             : !    CALL dbcsr_multiply("N","N",1.0_dp,matrix_qq,blk2,0.0_dp,tmp_qq,&
    1703             : !               filter_eps=eps_filter)
    1704             : !    CALL dbcsr_multiply("T","N",1.0_dp,blk2,tmp_qq,0.0_dp,matrix_qq,&
    1705             : !               filter_eps=eps_filter)
    1706             : !    CALL dbcsr_release(tmp_qq)
    1707             : !
    1708             : !    ! transform pq
    1709             : !    CALL dbcsr_init(tmp_pq)
    1710             : !    CALL dbcsr_create(tmp_pq,template=matrix_pq)
    1711             : !    CALL dbcsr_multiply("T","N",1.0_dp,blk,matrix_pq,0.0_dp,tmp_pq,&
    1712             : !               filter_eps=eps_filter)
    1713             : !    CALL dbcsr_multiply("N","N",1.0_dp,tmp_pq,blk2,0.0_dp,matrix_pq,&
    1714             : !               filter_eps=eps_filter)
    1715             : !    CALL dbcsr_release(tmp_pq)
    1716             : !
    1717             : !    ! transform qp
    1718             : !    CALL dbcsr_init(tmp_qp)
    1719             : !    CALL dbcsr_create(tmp_qp,template=matrix_qp)
    1720             : !    CALL dbcsr_multiply("N","N",1.0_dp,matrix_qp,blk,0.0_dp,tmp_qp,&
    1721             : !               filter_eps=eps_filter)
    1722             : !    CALL dbcsr_multiply("T","N",1.0_dp,blk2,tmp_qp,0.0_dp,matrix_qp,&
    1723             : !               filter_eps=eps_filter)
    1724             : !    CALL dbcsr_release(tmp_qp)
    1725             : !
    1726             : !    CALL dbcsr_release(blk2)
    1727             : !    CALL dbcsr_release(blk)
    1728             : !
    1729             : !    CALL timestop(handle)
    1730             : !
    1731             : !  END SUBROUTINE transform_matrices_to_blk_diag
    1732             : 
    1733             : ! **************************************************************************************************
    1734             : !> \brief computes oo, ov, vo, and vv blocks of the ks matrix
    1735             : !> \par History
    1736             : !>       2011.06 created [Rustam Z Khaliullin]
    1737             : !> \author Rustam Z Khaliullin
    1738             : ! **************************************************************************************************
    1739             : !  SUBROUTINE ct_step_env_execute(env)
    1740             : !
    1741             : !    TYPE(ct_step_env_type)                      :: env
    1742             : !
    1743             : !    CHARACTER(len=*), PARAMETER :: routineN = 'ct_step_env_execute', &
    1744             : !      routineP = moduleN//':'//routineN
    1745             : !
    1746             : !    INTEGER                                  :: handle
    1747             : !
    1748             : !    CALL timeset(routineN,handle)
    1749             : !
    1750             : !
    1751             : !    CALL timestop(handle)
    1752             : !
    1753             : !  END SUBROUTINE ct_step_env_execute
    1754             : 
    1755             : END MODULE ct_methods
    1756             : 

Generated by: LCOV version 1.15