1!--------------------------------------------------------------------------------------------------! 2! CP2K: A general program to perform molecular dynamics simulations ! 3! Copyright (C) 2000 - 2019 CP2K developers group ! 4!--------------------------------------------------------------------------------------------------! 5 6! ************************************************************************************************** 7!> \brief module that contains the algorithms to perform an itrative 8!> diagonalization by the block-Davidson approach 9!> P. Blaha, et al J. Comp. Physics, 229, (2010), 453-460 10!> Iterative diagonalization in augmented plane wave based 11!> methods in electronic structure calculations 12!> \par History 13!> 05.2011 created [MI] 14!> \author MI 15! ************************************************************************************************** 16MODULE qs_scf_block_davidson 17 18 USE cp_dbcsr_operations, ONLY: copy_dbcsr_to_fm,& 19 copy_fm_to_dbcsr,& 20 cp_dbcsr_m_by_n_from_row_template,& 21 cp_dbcsr_m_by_n_from_template,& 22 cp_dbcsr_sm_fm_multiply 23 USE cp_fm_basic_linalg, ONLY: cp_fm_column_scale,& 24 cp_fm_scale_and_add,& 25 cp_fm_symm,& 26 cp_fm_transpose,& 27 cp_fm_triangular_invert,& 28 cp_fm_upper_to_full 29 USE cp_fm_cholesky, ONLY: cp_fm_cholesky_decompose,& 30 cp_fm_cholesky_restore 31 USE cp_fm_diag, ONLY: choose_eigv_solver,& 32 cp_fm_power 33 USE cp_fm_struct, ONLY: cp_fm_struct_create,& 34 cp_fm_struct_release,& 35 cp_fm_struct_type 36 USE cp_fm_types, ONLY: cp_fm_create,& 37 cp_fm_get_diag,& 38 cp_fm_release,& 39 cp_fm_set_all,& 40 cp_fm_to_fm,& 41 cp_fm_to_fm_submat,& 42 cp_fm_type,& 43 cp_fm_vectorsnorm 44 USE cp_gemm_interface, ONLY: cp_gemm 45 USE dbcsr_api, ONLY: & 46 dbcsr_add, dbcsr_copy, dbcsr_create, dbcsr_get_diag, dbcsr_get_info, dbcsr_init_p, & 47 dbcsr_multiply, dbcsr_norm, dbcsr_norm_column, dbcsr_release_p, dbcsr_scale_by_vector, & 48 dbcsr_type, dbcsr_type_no_symmetry, dbcsr_type_real_default, dbcsr_type_symmetric 49 USE kinds, ONLY: dp 50 USE machine, ONLY: m_walltime 51 USE message_passing, ONLY: mp_sum 52 USE preconditioner, ONLY: apply_preconditioner 53 USE preconditioner_types, ONLY: preconditioner_type 54 USE qs_block_davidson_types, ONLY: davidson_type 55 USE qs_mo_types, ONLY: get_mo_set,& 56 mo_set_type 57#include "./base/base_uses.f90" 58 59 IMPLICIT NONE 60 PRIVATE 61 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_scf_block_davidson' 62 63 PUBLIC :: generate_extended_space, generate_extended_space_sparse 64 65CONTAINS 66 67! ************************************************************************************************** 68!> \brief ... 69!> \param bdav_env ... 70!> \param mo_set ... 71!> \param matrix_h ... 72!> \param matrix_s ... 73!> \param output_unit ... 74!> \param preconditioner ... 75! ************************************************************************************************** 76 SUBROUTINE generate_extended_space(bdav_env, mo_set, matrix_h, matrix_s, output_unit, & 77 preconditioner) 78 79 TYPE(davidson_type) :: bdav_env 80 TYPE(mo_set_type), POINTER :: mo_set 81 TYPE(dbcsr_type), POINTER :: matrix_h, matrix_s 82 INTEGER, INTENT(IN) :: output_unit 83 TYPE(preconditioner_type), OPTIONAL, POINTER :: preconditioner 84 85 CHARACTER(len=*), PARAMETER :: routineN = 'generate_extended_space', & 86 routineP = moduleN//':'//routineN 87 88 INTEGER :: handle, homo, i_first, i_last, imo, iter, j, jj, max_iter, n, nao, nmat, nmat2, & 89 nmo, nmo_converged, nmo_not_converged, nset, nset_conv, nset_not_conv 90 INTEGER, ALLOCATABLE, DIMENSION(:) :: iconv, inotconv 91 INTEGER, ALLOCATABLE, DIMENSION(:, :) :: iconv_set, inotconv_set 92 LOGICAL :: converged, do_apply_preconditioner 93 REAL(dp) :: lambda, max_norm, min_norm, t1, t2 94 REAL(dp), ALLOCATABLE, DIMENSION(:) :: ritz_coeff, vnorm 95 REAL(dp), DIMENSION(:), POINTER :: eig_not_conv, eigenvalues, evals 96 TYPE(cp_fm_struct_type), POINTER :: fm_struct_tmp 97 TYPE(cp_fm_type), POINTER :: c_conv, c_notconv, c_out, c_pz, c_z, & 98 h_block, h_fm, m_hc, m_sc, m_tmp, & 99 mo_coeff, mt_tmp, s_block, s_fm, & 100 v_block, w_block 101 TYPE(dbcsr_type), POINTER :: mo_coeff_b 102 103 CALL timeset(routineN, handle) 104 105 NULLIFY (mo_coeff, mo_coeff_b, eigenvalues) 106 107 do_apply_preconditioner = .FALSE. 108 IF (PRESENT(preconditioner)) do_apply_preconditioner = .TRUE. 109 CALL get_mo_set(mo_set=mo_set, mo_coeff=mo_coeff, mo_coeff_b=mo_coeff_b, eigenvalues=eigenvalues, & 110 nao=nao, nmo=nmo, homo=homo) 111 IF (do_apply_preconditioner) THEN 112 max_iter = bdav_env%max_iter 113 ELSE 114 max_iter = 1 115 END IF 116 117 NULLIFY (c_conv, c_notconv, c_out, c_z, c_pz, m_hc, m_sc, m_tmp, mt_tmp) 118 NULLIFY (h_block, h_fm, s_block, s_fm, v_block, w_block) 119 NULLIFY (evals, eig_not_conv) 120 t1 = m_walltime() 121 IF (output_unit > 0) THEN 122 WRITE (output_unit, "(T15,A,T23,A,T36,A,T49,A,T60,A,/,T8,A)") & 123 " Cycle ", " conv. MOS ", " B2MAX ", " B2MIN ", " Time", REPEAT("-", 60) 124 END IF 125 126 ALLOCATE (iconv(nmo)) 127 ALLOCATE (inotconv(nmo)) 128 ALLOCATE (ritz_coeff(nmo)) 129 ALLOCATE (vnorm(nmo)) 130 131 converged = .FALSE. 132 DO iter = 1, max_iter 133 134 ! compute Ritz values 135 ritz_coeff = 0.0_dp 136 CALL cp_fm_create(m_hc, mo_coeff%matrix_struct, name="hc") 137 CALL cp_dbcsr_sm_fm_multiply(matrix_h, mo_coeff, m_hc, nmo) 138 CALL cp_fm_create(m_sc, mo_coeff%matrix_struct, name="sc") 139 CALL cp_dbcsr_sm_fm_multiply(matrix_s, mo_coeff, m_sc, nmo) 140 141 CALL cp_fm_struct_create(fm_struct_tmp, nrow_global=nmo, ncol_global=nmo, & 142 context=mo_coeff%matrix_struct%context, & 143 para_env=mo_coeff%matrix_struct%para_env) 144 CALL cp_fm_create(m_tmp, fm_struct_tmp, name="matrix_tmp") 145 CALL cp_fm_struct_release(fm_struct_tmp) 146 147 CALL cp_gemm('T', 'N', nmo, nmo, nao, 1.0_dp, mo_coeff, m_hc, 0.0_dp, m_tmp) 148 CALL cp_fm_get_diag(m_tmp, ritz_coeff) 149 CALL cp_fm_release(m_tmp) 150 151 ! Check for converged eigenvectors 152! CALL cp_fm_create(c_z,mo_coeff%matrix_struct,name="tmp") 153 c_z => bdav_env%matrix_z 154 c_pz => bdav_env%matrix_pz 155 CALL cp_fm_to_fm(m_sc, c_z) 156 CALL cp_fm_column_scale(c_z, ritz_coeff) 157 CALL cp_fm_scale_and_add(-1.0_dp, c_z, 1.0_dp, m_hc) 158 CALL cp_fm_vectorsnorm(c_z, vnorm) 159 160 nmo_converged = 0 161 nmo_not_converged = 0 162 max_norm = 0.0_dp 163 min_norm = 1.e10_dp 164 DO imo = 1, nmo 165 max_norm = MAX(max_norm, vnorm(imo)) 166 min_norm = MIN(min_norm, vnorm(imo)) 167 END DO 168 iconv = 0 169 inotconv = 0 170 DO imo = 1, nmo 171 IF (vnorm(imo) <= bdav_env%eps_iter) THEN 172 nmo_converged = nmo_converged + 1 173 iconv(nmo_converged) = imo 174 ELSE 175 nmo_not_converged = nmo_not_converged + 1 176 inotconv(nmo_not_converged) = imo 177 END IF 178 END DO 179 180 IF (nmo_converged > 0) THEN 181 ALLOCATE (iconv_set(nmo_converged, 2)) 182 ALLOCATE (inotconv_set(nmo_not_converged, 2)) 183 i_last = iconv(1) 184 nset = 0 185 DO j = 1, nmo_converged 186 imo = iconv(j) 187 188 IF (imo == i_last + 1) THEN 189 i_last = imo 190 iconv_set(nset, 2) = imo 191 ELSE 192 i_last = imo 193 nset = nset + 1 194 iconv_set(nset, 1) = imo 195 iconv_set(nset, 2) = imo 196 END IF 197 END DO 198 nset_conv = nset 199 200 i_last = inotconv(1) 201 nset = 0 202 DO j = 1, nmo_not_converged 203 imo = inotconv(j) 204 205 IF (imo == i_last + 1) THEN 206 i_last = imo 207 inotconv_set(nset, 2) = imo 208 ELSE 209 i_last = imo 210 nset = nset + 1 211 inotconv_set(nset, 1) = imo 212 inotconv_set(nset, 2) = imo 213 END IF 214 END DO 215 nset_not_conv = nset 216 CALL cp_fm_release(m_sc) 217 CALL cp_fm_release(m_hc) 218 NULLIFY (c_z, c_pz) 219 END IF 220 221 IF (REAL(nmo_converged, dp)/REAL(nmo, dp) > bdav_env%conv_percent) THEN 222 converged = .TRUE. 223 DEALLOCATE (iconv_set) 224 DEALLOCATE (inotconv_set) 225 t2 = m_walltime() 226 IF (output_unit > 0) THEN 227 WRITE (output_unit, '(T16,I5,T24,I6,T33,E12.4,2x,E12.4,T60,F8.3)') & 228 iter, nmo_converged, max_norm, min_norm, t2 - t1 229 230 WRITE (output_unit, *) " Reached convergence in ", iter, & 231 " Davidson iterations" 232 END IF 233 234 EXIT 235 END IF 236 237 IF (nmo_converged > 0) THEN 238 CALL cp_fm_struct_create(fm_struct_tmp, nrow_global=nao, ncol_global=nao, & 239 context=mo_coeff%matrix_struct%context, & 240 para_env=mo_coeff%matrix_struct%para_env) 241 !allocate h_fm 242 CALL cp_fm_create(h_fm, fm_struct_tmp, name="matrix_tmp") 243 !allocate s_fm 244 CALL cp_fm_create(s_fm, fm_struct_tmp, name="matrix_tmp") 245 !copy matrix_h in h_fm 246 CALL copy_dbcsr_to_fm(matrix_h, h_fm) 247 CALL cp_fm_upper_to_full(h_fm, s_fm) 248 249 !copy matrix_s in s_fm 250! CALL cp_fm_set_all(s_fm,0.0_dp) 251 CALL copy_dbcsr_to_fm(matrix_s, s_fm) 252 253 !allocate c_out 254 CALL cp_fm_create(c_out, fm_struct_tmp, name="matrix_tmp") 255 ! set c_out to zero 256 CALL cp_fm_set_all(c_out, 0.0_dp) 257 CALL cp_fm_struct_release(fm_struct_tmp) 258 259 !allocate c_conv 260 CALL cp_fm_struct_create(fm_struct_tmp, nrow_global=nao, ncol_global=nmo_converged, & 261 context=mo_coeff%matrix_struct%context, & 262 para_env=mo_coeff%matrix_struct%para_env) 263 CALL cp_fm_create(c_conv, fm_struct_tmp, name="c_conv") 264 CALL cp_fm_set_all(c_conv, 0.0_dp) 265 !allocate m_tmp 266 CALL cp_fm_create(m_tmp, fm_struct_tmp, name="m_tmp_nxmc") 267 CALL cp_fm_struct_release(fm_struct_tmp) 268 END IF 269 270 !allocate c_notconv 271 CALL cp_fm_struct_create(fm_struct_tmp, nrow_global=nao, ncol_global=nmo_not_converged, & 272 context=mo_coeff%matrix_struct%context, & 273 para_env=mo_coeff%matrix_struct%para_env) 274 CALL cp_fm_create(c_notconv, fm_struct_tmp, name="c_notconv") 275 CALL cp_fm_set_all(c_notconv, 0.0_dp) 276 IF (nmo_converged > 0) THEN 277 CALL cp_fm_create(m_hc, fm_struct_tmp, name="m_hc") 278 CALL cp_fm_create(m_sc, fm_struct_tmp, name="m_sc") 279 !allocate c_z 280 CALL cp_fm_create(c_z, fm_struct_tmp, name="c_z") 281 CALL cp_fm_create(c_pz, fm_struct_tmp, name="c_pz") 282 CALL cp_fm_set_all(c_z, 0.0_dp) 283 284 ! sum contributions to c_out 285 jj = 1 286 DO j = 1, nset_conv 287 i_first = iconv_set(j, 1) 288 i_last = iconv_set(j, 2) 289 n = i_last - i_first + 1 290 CALL cp_fm_to_fm_submat(mo_coeff, c_conv, nao, n, 1, i_first, 1, jj) 291 jj = jj + n 292 END DO 293 CALL cp_fm_symm('L', 'U', nao, nmo_converged, 1.0_dp, s_fm, c_conv, 0.0_dp, m_tmp) 294 CALL cp_gemm('N', 'T', nao, nao, nmo_converged, 1.0_dp, m_tmp, m_tmp, 0.0_dp, c_out) 295 296 ! project c_out out of H 297 lambda = 100.0_dp*ABS(eigenvalues(homo)) 298 CALL cp_fm_scale_and_add(lambda, c_out, 1.0_dp, h_fm) 299 CALL cp_fm_release(m_tmp) 300 CALL cp_fm_release(h_fm) 301 302 END IF 303 304 !allocate m_tmp 305 CALL cp_fm_create(m_tmp, fm_struct_tmp, name="m_tmp_nxm") 306 CALL cp_fm_struct_release(fm_struct_tmp) 307 IF (nmo_converged > 0) THEN 308 ALLOCATE (eig_not_conv(nmo_not_converged)) 309 jj = 1 310 DO j = 1, nset_not_conv 311 i_first = inotconv_set(j, 1) 312 i_last = inotconv_set(j, 2) 313 n = i_last - i_first + 1 314 CALL cp_fm_to_fm_submat(mo_coeff, c_notconv, nao, n, 1, i_first, 1, jj) 315 eig_not_conv(jj:jj + n - 1) = ritz_coeff(i_first:i_last) 316 jj = jj + n 317 END DO 318 CALL cp_gemm('N', 'N', nao, nmo_not_converged, nao, 1.0_dp, c_out, c_notconv, 0.0_dp, m_hc) 319 CALL cp_fm_symm('L', 'U', nao, nmo_not_converged, 1.0_dp, s_fm, c_notconv, 0.0_dp, m_sc) 320 ! extend suspace using only the not converged vectors 321 CALL cp_fm_to_fm(m_sc, m_tmp) 322 CALL cp_fm_column_scale(m_tmp, eig_not_conv) 323 CALL cp_fm_scale_and_add(-1.0_dp, m_tmp, 1.0_dp, m_hc) 324 DEALLOCATE (eig_not_conv) 325 CALL cp_fm_to_fm(m_tmp, c_z) 326 ELSE 327 CALL cp_fm_to_fm(mo_coeff, c_notconv) 328 END IF 329 330 !preconditioner 331 IF (do_apply_preconditioner) THEN 332 IF (preconditioner%in_use /= 0) THEN 333 CALL apply_preconditioner(preconditioner, c_z, c_pz) 334 ELSE 335 CALL cp_fm_to_fm(c_z, c_pz) 336 ENDIF 337 ELSE 338 CALL cp_fm_to_fm(c_z, c_pz) 339 END IF 340 CALL cp_fm_release(m_tmp) 341 342 CALL cp_fm_struct_create(fm_struct_tmp, nrow_global=nmo_not_converged, ncol_global=nmo_not_converged, & 343 context=mo_coeff%matrix_struct%context, & 344 para_env=mo_coeff%matrix_struct%para_env) 345 346 CALL cp_fm_create(m_tmp, fm_struct_tmp, name="m_tmp_mxm") 347 CALL cp_fm_create(mt_tmp, fm_struct_tmp, name="mt_tmp_mxm") 348 CALL cp_fm_struct_release(fm_struct_tmp) 349 350 nmat = nmo_not_converged 351 nmat2 = 2*nmo_not_converged 352 CALL cp_fm_struct_create(fm_struct_tmp, nrow_global=nmat2, ncol_global=nmat2, & 353 context=mo_coeff%matrix_struct%context, & 354 para_env=mo_coeff%matrix_struct%para_env) 355 356 CALL cp_fm_create(s_block, fm_struct_tmp, name="sb") 357 CALL cp_fm_create(h_block, fm_struct_tmp, name="hb") 358 CALL cp_fm_create(v_block, fm_struct_tmp, name="vb") 359 CALL cp_fm_create(w_block, fm_struct_tmp, name="wb") 360 ALLOCATE (evals(nmat2)) 361 362 CALL cp_fm_struct_release(fm_struct_tmp) 363 364 ! compute CSC 365 CALL cp_fm_set_all(s_block, 0.0_dp, 1.0_dp) 366 367 ! compute CHC 368 CALL cp_gemm('T', 'N', nmat, nmat, nao, 1.0_dp, c_notconv, m_hc, 0.0_dp, m_tmp) 369 CALL cp_fm_to_fm_submat(m_tmp, h_block, nmat, nmat, 1, 1, 1, 1) 370 371 ! compute ZSC 372 CALL cp_gemm('T', 'N', nmat, nmat, nao, 1.0_dp, c_pz, m_sc, 0.0_dp, m_tmp) 373 CALL cp_fm_to_fm_submat(m_tmp, s_block, nmat, nmat, 1, 1, 1 + nmat, 1) 374 CALL cp_fm_transpose(m_tmp, mt_tmp) 375 CALL cp_fm_to_fm_submat(mt_tmp, s_block, nmat, nmat, 1, 1, 1, 1 + nmat) 376 ! compute ZHC 377 CALL cp_gemm('T', 'N', nmat, nmat, nao, 1.0_dp, c_pz, m_hc, 0.0_dp, m_tmp) 378 CALL cp_fm_to_fm_submat(m_tmp, h_block, nmat, nmat, 1, 1, 1 + nmat, 1) 379 CALL cp_fm_transpose(m_tmp, mt_tmp) 380 CALL cp_fm_to_fm_submat(mt_tmp, h_block, nmat, nmat, 1, 1, 1, 1 + nmat) 381 382 CALL cp_fm_release(mt_tmp) 383 384 ! reuse m_sc and m_hc to computr HZ and SZ 385 IF (nmo_converged > 0) THEN 386 CALL cp_gemm('N', 'N', nao, nmat, nao, 1.0_dp, c_out, c_pz, 0.0_dp, m_hc) 387 CALL cp_fm_symm('L', 'U', nao, nmo_not_converged, 1.0_dp, s_fm, c_pz, 0.0_dp, m_sc) 388 389 CALL cp_fm_release(c_out) 390 CALL cp_fm_release(c_conv) 391 CALL cp_fm_release(s_fm) 392 ELSE 393 CALL cp_dbcsr_sm_fm_multiply(matrix_h, c_pz, m_hc, nmo) 394 CALL cp_dbcsr_sm_fm_multiply(matrix_s, c_pz, m_sc, nmo) 395 END IF 396 397 ! compute ZSZ 398 CALL cp_gemm('T', 'N', nmat, nmat, nao, 1.0_dp, c_pz, m_sc, 0.0_dp, m_tmp) 399 CALL cp_fm_to_fm_submat(m_tmp, s_block, nmat, nmat, 1, 1, 1 + nmat, 1 + nmat) 400 ! compute ZHZ 401 CALL cp_gemm('T', 'N', nmat, nmat, nao, 1.0_dp, c_pz, m_hc, 0.0_dp, m_tmp) 402 CALL cp_fm_to_fm_submat(m_tmp, h_block, nmat, nmat, 1, 1, 1 + nmat, 1 + nmat) 403 404 CALL cp_fm_release(m_sc) 405 406 ! solution of the reduced eigenvalues problem 407 CALL reduce_extended_space(s_block, h_block, v_block, w_block, evals, nmat2) 408 409 ! extract egenvectors 410 CALL cp_fm_to_fm_submat(v_block, m_tmp, nmat, nmat, 1, 1, 1, 1) 411 CALL cp_gemm('N', 'N', nao, nmat, nmat, 1.0_dp, c_notconv, m_tmp, 0.0_dp, m_hc) 412 CALL cp_fm_to_fm_submat(v_block, m_tmp, nmat, nmat, 1 + nmat, 1, 1, 1) 413 CALL cp_gemm('N', 'N', nao, nmat, nmat, 1.0_dp, c_pz, m_tmp, 1.0_dp, m_hc) 414 415 CALL cp_fm_release(m_tmp) 416 417 CALL cp_fm_release(c_notconv) 418 CALL cp_fm_release(s_block) 419 CALL cp_fm_release(h_block) 420 CALL cp_fm_release(w_block) 421 CALL cp_fm_release(v_block) 422 423 IF (nmo_converged > 0) THEN 424 CALL cp_fm_release(c_z) 425 CALL cp_fm_release(c_pz) 426 jj = 1 427 DO j = 1, nset_not_conv 428 i_first = inotconv_set(j, 1) 429 i_last = inotconv_set(j, 2) 430 n = i_last - i_first + 1 431 CALL cp_fm_to_fm_submat(m_hc, mo_coeff, nao, n, 1, jj, 1, i_first) 432 eigenvalues(i_first:i_last) = evals(jj:jj + n - 1) 433 jj = jj + n 434 END DO 435 DEALLOCATE (iconv_set) 436 DEALLOCATE (inotconv_set) 437 ELSE 438 CALL cp_fm_to_fm(m_hc, mo_coeff) 439 eigenvalues(1:nmo) = evals(1:nmo) 440 END IF 441 DEALLOCATE (evals) 442 443 CALL cp_fm_release(m_hc) 444 445 CALL copy_fm_to_dbcsr(mo_coeff, mo_coeff_b) !fm->dbcsr 446 447 t2 = m_walltime() 448 IF (output_unit > 0) THEN 449 WRITE (output_unit, '(T16,I5,T24,I6,T33,E12.4,2x,E12.4,T60,F8.3)') & 450 iter, nmo_converged, max_norm, min_norm, t2 - t1 451 END IF 452 t1 = m_walltime() 453 454 END DO ! iter 455 456 DEALLOCATE (iconv) 457 DEALLOCATE (inotconv) 458 DEALLOCATE (ritz_coeff) 459 DEALLOCATE (vnorm) 460 461 CALL timestop(handle) 462 END SUBROUTINE generate_extended_space 463 464! ************************************************************************************************** 465!> \brief ... 466!> \param bdav_env ... 467!> \param mo_set ... 468!> \param matrix_h ... 469!> \param matrix_s ... 470!> \param output_unit ... 471!> \param preconditioner ... 472! ************************************************************************************************** 473 SUBROUTINE generate_extended_space_sparse(bdav_env, mo_set, matrix_h, matrix_s, output_unit, & 474 preconditioner) 475 476 TYPE(davidson_type) :: bdav_env 477 TYPE(mo_set_type), POINTER :: mo_set 478 TYPE(dbcsr_type), POINTER :: matrix_h, matrix_s 479 INTEGER, INTENT(IN) :: output_unit 480 TYPE(preconditioner_type), OPTIONAL, POINTER :: preconditioner 481 482 CHARACTER(len=*), PARAMETER :: routineN = 'generate_extended_space_sparse', & 483 routineP = moduleN//':'//routineN 484 485 INTEGER :: handle, homo, i_first, i_last, imo, iter, j, jj, k, max_iter, n, nao, nmat, & 486 nmat2, nmo, nmo_converged, nmo_not_converged, nset, nset_conv, nset_not_conv 487 INTEGER, ALLOCATABLE, DIMENSION(:) :: iconv, inotconv 488 INTEGER, ALLOCATABLE, DIMENSION(:, :) :: iconv_set, inotconv_set 489 LOGICAL :: converged, do_apply_preconditioner 490 REAL(dp) :: lambda, max_norm, min_norm, t1, t2 491 REAL(dp), ALLOCATABLE, DIMENSION(:) :: eig_not_conv, evals, ritz_coeff, vnorm 492 REAL(dp), DIMENSION(:), POINTER :: eigenvalues 493 TYPE(cp_fm_struct_type), POINTER :: fm_struct_tmp 494 TYPE(cp_fm_type), POINTER :: h_block, matrix_mm_fm, matrix_mmt_fm, matrix_nm_fm, & 495 matrix_z_fm, mo_coeff, mo_conv_fm, mo_notconv_fm, s_block, v_block, w_block 496 TYPE(dbcsr_type), POINTER :: c_out, matrix_hc, matrix_mm, matrix_pz, & 497 matrix_sc, matrix_z, mo_coeff_b, & 498 mo_conv, mo_notconv, smo_conv 499 500 CALL timeset(routineN, handle) 501 502 do_apply_preconditioner = .FALSE. 503 IF (PRESENT(preconditioner)) do_apply_preconditioner = .TRUE. 504 505 NULLIFY (mo_coeff, mo_coeff_b, matrix_hc, matrix_sc, matrix_z, matrix_pz, matrix_mm) 506 NULLIFY (mo_conv_fm, mo_notconv_fm, mo_conv, mo_notconv, smo_conv, c_out) 507 NULLIFY (matrix_mm_fm, matrix_mmt_fm, mo_coeff, matrix_nm_fm, matrix_z_fm) 508 NULLIFY (h_block, s_block, v_block, w_block) 509 NULLIFY (fm_struct_tmp) 510 CALL get_mo_set(mo_set=mo_set, mo_coeff=mo_coeff, mo_coeff_b=mo_coeff_b, & 511 eigenvalues=eigenvalues, homo=homo, nao=nao, nmo=nmo) 512 IF (do_apply_preconditioner) THEN 513 max_iter = bdav_env%max_iter 514 ELSE 515 max_iter = 1 516 END IF 517 518 t1 = m_walltime() 519 IF (output_unit > 0) THEN 520 WRITE (output_unit, "(T15,A,T23,A,T36,A,T49,A,T60,A,/,T8,A)") & 521 " Cycle ", " conv. MOS ", " B2MAX ", " B2MIN ", " Time", REPEAT("-", 60) 522 END IF 523 524 ! Allocate array for Ritz values 525 ALLOCATE (ritz_coeff(nmo)) 526 ALLOCATE (iconv(nmo)) 527 ALLOCATE (inotconv(nmo)) 528 ALLOCATE (vnorm(nmo)) 529 530 converged = .FALSE. 531 DO iter = 1, max_iter 532 NULLIFY (c_out, mo_conv, mo_notconv_fm, mo_notconv) 533 ! Prepare HC and SC, using mo_coeff_b (sparse), these are still sparse 534 CALL dbcsr_init_p(matrix_hc) 535 CALL dbcsr_create(matrix_hc, template=mo_coeff_b, & 536 name="matrix_hc", & 537 matrix_type=dbcsr_type_no_symmetry, & 538 nze=0, data_type=dbcsr_type_real_default) 539 CALL dbcsr_init_p(matrix_sc) 540 CALL dbcsr_create(matrix_sc, template=mo_coeff_b, & 541 name="matrix_sc", & 542 matrix_type=dbcsr_type_no_symmetry, & 543 nze=0, data_type=dbcsr_type_real_default) 544 545 CALL dbcsr_get_info(mo_coeff_b, nfullrows_total=n, nfullcols_total=k) 546 CALL dbcsr_multiply('n', 'n', 1.0_dp, matrix_h, mo_coeff_b, 0.0_dp, matrix_hc, last_column=k) 547 CALL dbcsr_multiply('n', 'n', 1.0_dp, matrix_s, mo_coeff_b, 0.0_dp, matrix_sc, last_column=k) 548 549 ! compute Ritz values 550 ritz_coeff = 0.0_dp 551 ! Allocate Sparse matrices: nmoxnmo 552 ! matrix_mm 553 554 CALL dbcsr_init_p(matrix_mm) 555 CALL cp_dbcsr_m_by_n_from_template(matrix_mm, template=matrix_s, m=nmo, n=nmo, & 556 sym=dbcsr_type_no_symmetry) 557 558 CALL dbcsr_multiply('t', 'n', 1.0_dp, mo_coeff_b, matrix_hc, 0.0_dp, matrix_mm, last_column=k) 559 CALL dbcsr_get_diag(matrix_mm, ritz_coeff) 560 CALL mp_sum(ritz_coeff, mo_coeff%matrix_struct%para_env%group) 561 562 ! extended subspace P Z = P [H - theta S]C this ia another matrix of type and size as mo_coeff_b 563 CALL dbcsr_init_p(matrix_z) 564 CALL dbcsr_create(matrix_z, template=mo_coeff_b, & 565 name="matrix_z", & 566 matrix_type=dbcsr_type_no_symmetry, & 567 nze=0, data_type=dbcsr_type_real_default) 568 CALL dbcsr_copy(matrix_z, matrix_sc) 569 CALL dbcsr_scale_by_vector(matrix_z, ritz_coeff, side='right') 570 CALL dbcsr_add(matrix_z, matrix_hc, -1.0_dp, 1.0_dp) 571 572 ! Check for converged eigenvectors 573 vnorm = 0.0_dp 574 CALL dbcsr_norm(matrix_z, which_norm=dbcsr_norm_column, norm_vector=vnorm) 575 nmo_converged = 0 576 nmo_not_converged = 0 577 max_norm = 0.0_dp 578 min_norm = 1.e10_dp 579 DO imo = 1, nmo 580 max_norm = MAX(max_norm, vnorm(imo)) 581 min_norm = MIN(min_norm, vnorm(imo)) 582 END DO 583 iconv = 0 584 inotconv = 0 585 586 DO imo = 1, nmo 587 IF (vnorm(imo) <= bdav_env%eps_iter) THEN 588 nmo_converged = nmo_converged + 1 589 iconv(nmo_converged) = imo 590 ELSE 591 nmo_not_converged = nmo_not_converged + 1 592 inotconv(nmo_not_converged) = imo 593 END IF 594 END DO 595 596 IF (nmo_converged > 0) THEN 597 ALLOCATE (iconv_set(nmo_converged, 2)) 598 ALLOCATE (inotconv_set(nmo_not_converged, 2)) 599 i_last = iconv(1) 600 nset = 0 601 DO j = 1, nmo_converged 602 imo = iconv(j) 603 604 IF (imo == i_last + 1) THEN 605 i_last = imo 606 iconv_set(nset, 2) = imo 607 ELSE 608 i_last = imo 609 nset = nset + 1 610 iconv_set(nset, 1) = imo 611 iconv_set(nset, 2) = imo 612 END IF 613 END DO 614 nset_conv = nset 615 616 i_last = inotconv(1) 617 nset = 0 618 DO j = 1, nmo_not_converged 619 imo = inotconv(j) 620 621 IF (imo == i_last + 1) THEN 622 i_last = imo 623 inotconv_set(nset, 2) = imo 624 ELSE 625 i_last = imo 626 nset = nset + 1 627 inotconv_set(nset, 1) = imo 628 inotconv_set(nset, 2) = imo 629 END IF 630 END DO 631 nset_not_conv = nset 632 633 CALL dbcsr_release_p(matrix_hc) 634 CALL dbcsr_release_p(matrix_sc) 635 CALL dbcsr_release_p(matrix_z) 636 CALL dbcsr_release_p(matrix_mm) 637 END IF 638 639 IF (REAL(nmo_converged, dp)/REAL(nmo, dp) > bdav_env%conv_percent) THEN 640 DEALLOCATE (iconv_set) 641 642 DEALLOCATE (inotconv_set) 643 644 converged = .TRUE. 645 t2 = m_walltime() 646 IF (output_unit > 0) THEN 647 WRITE (output_unit, '(T16,I5,T24,I6,T33,E12.4,2x,E12.4,T60,F8.3)') & 648 iter, nmo_converged, max_norm, min_norm, t2 - t1 649 650 WRITE (output_unit, *) " Reached convergence in ", iter, & 651 " Davidson iterations" 652 END IF 653 654 EXIT 655 END IF 656 657 IF (nmo_converged > 0) THEN 658 659 !allocate mo_conv_fm 660 CALL cp_fm_struct_create(fm_struct_tmp, nrow_global=nao, ncol_global=nmo_converged, & 661 context=mo_coeff%matrix_struct%context, & 662 para_env=mo_coeff%matrix_struct%para_env) 663 CALL cp_fm_create(mo_conv_fm, fm_struct_tmp, name="mo_conv_fm") 664 665 CALL cp_fm_struct_release(fm_struct_tmp) 666 667 ! extract mo_conv from mo_coeff full matrix 668 jj = 1 669 DO j = 1, nset_conv 670 i_first = iconv_set(j, 1) 671 i_last = iconv_set(j, 2) 672 n = i_last - i_first + 1 673 CALL cp_fm_to_fm_submat(mo_coeff, mo_conv_fm, nao, n, 1, i_first, 1, jj) 674 jj = jj + n 675 END DO 676 677 ! allocate c_out sparse matrix, to project out the converged MOS 678 CALL dbcsr_init_p(c_out) 679 CALL dbcsr_create(c_out, template=matrix_s, & 680 name="c_out", & 681 matrix_type=dbcsr_type_symmetric, & 682 nze=0, data_type=dbcsr_type_real_default) 683 684 ! allocate mo_conv sparse 685 CALL dbcsr_init_p(mo_conv) 686 CALL cp_dbcsr_m_by_n_from_row_template(mo_conv, template=matrix_s, n=nmo_converged, & 687 sym=dbcsr_type_no_symmetry) 688 689 CALL dbcsr_init_p(smo_conv) 690 CALL cp_dbcsr_m_by_n_from_row_template(smo_conv, template=matrix_s, n=nmo_converged, & 691 sym=dbcsr_type_no_symmetry) 692 693 CALL copy_fm_to_dbcsr(mo_conv_fm, mo_conv) !fm->dbcsr 694 695 CALL dbcsr_multiply('n', 'n', 1.0_dp, matrix_s, mo_conv, 0.0_dp, smo_conv, last_column=nmo_converged) 696 CALL dbcsr_multiply('n', 't', 1.0_dp, smo_conv, smo_conv, 0.0_dp, c_out, last_column=nao) 697 ! project c_out out of H 698 lambda = 100.0_dp*ABS(eigenvalues(homo)) 699 CALL dbcsr_add(c_out, matrix_h, lambda, 1.0_dp) 700 701 CALL dbcsr_release_p(mo_conv) 702 CALL dbcsr_release_p(smo_conv) 703 CALL cp_fm_release(mo_conv_fm) 704 705 !allocate c_notconv_fm 706 CALL cp_fm_struct_create(fm_struct_tmp, nrow_global=nao, ncol_global=nmo_not_converged, & 707 context=mo_coeff%matrix_struct%context, & 708 para_env=mo_coeff%matrix_struct%para_env) 709 CALL cp_fm_create(mo_notconv_fm, fm_struct_tmp, name="mo_notconv_fm") 710 CALL cp_fm_struct_release(fm_struct_tmp) 711 712 ! extract mo_notconv from mo_coeff full matrix 713 ALLOCATE (eig_not_conv(nmo_not_converged)) 714 715 jj = 1 716 DO j = 1, nset_not_conv 717 i_first = inotconv_set(j, 1) 718 i_last = inotconv_set(j, 2) 719 n = i_last - i_first + 1 720 CALL cp_fm_to_fm_submat(mo_coeff, mo_notconv_fm, nao, n, 1, i_first, 1, jj) 721 eig_not_conv(jj:jj + n - 1) = ritz_coeff(i_first:i_last) 722 jj = jj + n 723 END DO 724 725 ! allocate mo_conv sparse 726 CALL dbcsr_init_p(mo_notconv) 727 CALL cp_dbcsr_m_by_n_from_row_template(mo_notconv, template=matrix_s, n=nmo_not_converged, & 728 sym=dbcsr_type_no_symmetry) 729 730 CALL dbcsr_init_p(matrix_hc) 731 CALL cp_dbcsr_m_by_n_from_row_template(matrix_hc, template=matrix_s, n=nmo_not_converged, & 732 sym=dbcsr_type_no_symmetry) 733 734 CALL dbcsr_init_p(matrix_sc) 735 CALL cp_dbcsr_m_by_n_from_row_template(matrix_sc, template=matrix_s, n=nmo_not_converged, & 736 sym=dbcsr_type_no_symmetry) 737 738 CALL dbcsr_init_p(matrix_z) 739 CALL cp_dbcsr_m_by_n_from_row_template(matrix_z, template=matrix_s, n=nmo_not_converged, & 740 sym=dbcsr_type_no_symmetry) 741 742 CALL copy_fm_to_dbcsr(mo_notconv_fm, mo_notconv) !fm->dbcsr 743 744 CALL dbcsr_multiply('n', 'n', 1.0_dp, c_out, mo_notconv, 0.0_dp, matrix_hc, & 745 last_column=nmo_not_converged) 746 CALL dbcsr_multiply('n', 'n', 1.0_dp, matrix_s, mo_notconv, 0.0_dp, matrix_sc, & 747 last_column=nmo_not_converged) 748 749 CALL dbcsr_copy(matrix_z, matrix_sc) 750 CALL dbcsr_scale_by_vector(matrix_z, eig_not_conv, side='right') 751 CALL dbcsr_add(matrix_z, matrix_hc, -1.0_dp, 1.0_dp) 752 753 DEALLOCATE (eig_not_conv) 754 755 ! matrix_mm 756 CALL dbcsr_init_p(matrix_mm) 757 CALL cp_dbcsr_m_by_n_from_template(matrix_mm, template=matrix_s, m=nmo_not_converged, n=nmo_not_converged, & 758 sym=dbcsr_type_no_symmetry) 759 760 CALL dbcsr_multiply('t', 'n', 1.0_dp, mo_notconv, matrix_hc, 0.0_dp, matrix_mm, & 761 last_column=nmo_not_converged) 762 763 ELSE 764 mo_notconv => mo_coeff_b 765 mo_notconv_fm => mo_coeff 766 c_out => matrix_h 767 END IF 768 769 ! allocate matrix_pz using as template matrix_z 770 CALL dbcsr_init_p(matrix_pz) 771 CALL dbcsr_create(matrix_pz, template=matrix_z, & 772 name="matrix_pz", & 773 matrix_type=dbcsr_type_no_symmetry, & 774 nze=0, data_type=dbcsr_type_real_default) 775 776 IF (do_apply_preconditioner) THEN 777 IF (preconditioner%in_use /= 0) THEN 778 CALL apply_preconditioner(preconditioner, matrix_z, matrix_pz) 779 ELSE 780 CALL dbcsr_copy(matrix_pz, matrix_z) 781 END IF 782 ELSE 783 CALL dbcsr_copy(matrix_pz, matrix_z) 784 END IF 785 786 !allocate NMOxNMO full matrices 787 nmat = nmo_not_converged 788 CALL cp_fm_struct_create(fm_struct_tmp, nrow_global=nmat, ncol_global=nmat, & 789 context=mo_coeff%matrix_struct%context, & 790 para_env=mo_coeff%matrix_struct%para_env) 791 CALL cp_fm_create(matrix_mm_fm, fm_struct_tmp, name="m_tmp_mxm") 792 CALL cp_fm_create(matrix_mmt_fm, fm_struct_tmp, name="mt_tmp_mxm") 793 CALL cp_fm_struct_release(fm_struct_tmp) 794 795 !allocate 2NMOx2NMO full matrices 796 nmat2 = 2*nmo_not_converged 797 CALL cp_fm_struct_create(fm_struct_tmp, nrow_global=nmat2, ncol_global=nmat2, & 798 context=mo_coeff%matrix_struct%context, & 799 para_env=mo_coeff%matrix_struct%para_env) 800 801 CALL cp_fm_create(s_block, fm_struct_tmp, name="sb") 802 CALL cp_fm_create(h_block, fm_struct_tmp, name="hb") 803 CALL cp_fm_create(v_block, fm_struct_tmp, name="vb") 804 CALL cp_fm_create(w_block, fm_struct_tmp, name="wb") 805 ALLOCATE (evals(nmat2)) 806 CALL cp_fm_struct_release(fm_struct_tmp) 807 808 ! compute CSC 809 CALL cp_fm_set_all(s_block, 0.0_dp, 1.0_dp) 810 ! compute CHC 811 CALL copy_dbcsr_to_fm(matrix_mm, matrix_mm_fm) 812 CALL cp_fm_to_fm_submat(matrix_mm_fm, h_block, nmat, nmat, 1, 1, 1, 1) 813 814 ! compute the bottom left ZSC (top right is transpose) 815 CALL dbcsr_multiply('t', 'n', 1.0_dp, matrix_pz, matrix_sc, 0.0_dp, matrix_mm, last_column=nmat) 816 ! set the bottom left part of S[C,Z] block matrix ZSC 817 !copy sparse to full 818 CALL copy_dbcsr_to_fm(matrix_mm, matrix_mm_fm) 819 CALL cp_fm_to_fm_submat(matrix_mm_fm, s_block, nmat, nmat, 1, 1, 1 + nmat, 1) 820 CALL cp_fm_transpose(matrix_mm_fm, matrix_mmt_fm) 821 CALL cp_fm_to_fm_submat(matrix_mmt_fm, s_block, nmat, nmat, 1, 1, 1, 1 + nmat) 822 823 ! compute the bottom left ZHC (top right is transpose) 824 CALL dbcsr_multiply('t', 'n', 1.0_dp, matrix_pz, matrix_hc, 0.0_dp, matrix_mm, last_column=nmat) 825 ! set the bottom left part of S[C,Z] block matrix ZHC 826 CALL copy_dbcsr_to_fm(matrix_mm, matrix_mm_fm) 827 CALL cp_fm_to_fm_submat(matrix_mm_fm, h_block, nmat, nmat, 1, 1, 1 + nmat, 1) 828 CALL cp_fm_transpose(matrix_mm_fm, matrix_mmt_fm) 829 CALL cp_fm_to_fm_submat(matrix_mmt_fm, h_block, nmat, nmat, 1, 1, 1, 1 + nmat) 830 831 CALL cp_fm_release(matrix_mmt_fm) 832 833 ! (reuse matrix_sc and matrix_hc to computr HZ and SZ) 834 CALL dbcsr_get_info(matrix_pz, nfullrows_total=n, nfullcols_total=k) 835 CALL dbcsr_multiply('n', 'n', 1.0_dp, c_out, matrix_pz, 0.0_dp, matrix_hc, last_column=k) 836 CALL dbcsr_multiply('n', 'n', 1.0_dp, matrix_s, matrix_pz, 0.0_dp, matrix_sc, last_column=k) 837 838 ! compute the bottom right ZSZ 839 CALL dbcsr_multiply('t', 'n', 1.0_dp, matrix_pz, matrix_sc, 0.0_dp, matrix_mm, last_column=k) 840 ! set the bottom right part of S[C,Z] block matrix ZSZ 841 CALL copy_dbcsr_to_fm(matrix_mm, matrix_mm_fm) 842 CALL cp_fm_to_fm_submat(matrix_mm_fm, s_block, nmat, nmat, 1, 1, 1 + nmat, 1 + nmat) 843 844 ! compute the bottom right ZHZ 845 CALL dbcsr_multiply('t', 'n', 1.0_dp, matrix_pz, matrix_hc, 0.0_dp, matrix_mm, last_column=k) 846 ! set the bottom right part of H[C,Z] block matrix ZHZ 847 CALL copy_dbcsr_to_fm(matrix_mm, matrix_mm_fm) 848 CALL cp_fm_to_fm_submat(matrix_mm_fm, h_block, nmat, nmat, 1, 1, 1 + nmat, 1 + nmat) 849 850 CALL dbcsr_release_p(matrix_mm) 851 CALL dbcsr_release_p(matrix_sc) 852 CALL dbcsr_release_p(matrix_hc) 853 854 CALL reduce_extended_space(s_block, h_block, v_block, w_block, evals, nmat2) 855 856 ! allocate two (nao x nmat) full matrix 857 CALL cp_fm_struct_create(fm_struct_tmp, nrow_global=nao, ncol_global=nmat, & 858 context=mo_coeff%matrix_struct%context, & 859 para_env=mo_coeff%matrix_struct%para_env) 860 CALL cp_fm_create(matrix_nm_fm, fm_struct_tmp, name="m_nxm") 861 CALL cp_fm_create(matrix_z_fm, fm_struct_tmp, name="m_nxm") 862 CALL cp_fm_struct_release(fm_struct_tmp) 863 864 CALL copy_dbcsr_to_fm(matrix_pz, matrix_z_fm) 865 ! extract egenvectors 866 CALL cp_fm_to_fm_submat(v_block, matrix_mm_fm, nmat, nmat, 1, 1, 1, 1) 867 CALL cp_gemm('N', 'N', nao, nmat, nmat, 1.0_dp, mo_notconv_fm, matrix_mm_fm, 0.0_dp, matrix_nm_fm) 868 CALL cp_fm_to_fm_submat(v_block, matrix_mm_fm, nmat, nmat, 1 + nmat, 1, 1, 1) 869 CALL cp_gemm('N', 'N', nao, nmat, nmat, 1.0_dp, matrix_z_fm, matrix_mm_fm, 1.0_dp, matrix_nm_fm) 870 871 CALL dbcsr_release_p(matrix_z) 872 CALL dbcsr_release_p(matrix_pz) 873 CALL cp_fm_release(matrix_z_fm) 874 CALL cp_fm_release(s_block) 875 CALL cp_fm_release(h_block) 876 CALL cp_fm_release(w_block) 877 CALL cp_fm_release(v_block) 878 CALL cp_fm_release(matrix_mm_fm) 879 880 ! in case some vector are already converged only a subset of vectors are copied in the MOS 881 IF (nmo_converged > 0) THEN 882 jj = 1 883 DO j = 1, nset_not_conv 884 i_first = inotconv_set(j, 1) 885 i_last = inotconv_set(j, 2) 886 n = i_last - i_first + 1 887 CALL cp_fm_to_fm_submat(matrix_nm_fm, mo_coeff, nao, n, 1, jj, 1, i_first) 888 eigenvalues(i_first:i_last) = evals(jj:jj + n - 1) 889 jj = jj + n 890 END DO 891 DEALLOCATE (iconv_set) 892 DEALLOCATE (inotconv_set) 893 894 CALL dbcsr_release_p(mo_notconv) 895 CALL dbcsr_release_p(c_out) 896 CALL cp_fm_release(mo_notconv_fm) 897 ELSE 898 CALL cp_fm_to_fm(matrix_nm_fm, mo_coeff) 899 eigenvalues(1:nmo) = evals(1:nmo) 900 END IF 901 DEALLOCATE (evals) 902 903 CALL cp_fm_release(matrix_nm_fm) 904 CALL copy_fm_to_dbcsr(mo_coeff, mo_coeff_b) !fm->dbcsr 905 906 t2 = m_walltime() 907 IF (output_unit > 0) THEN 908 WRITE (output_unit, '(T16,I5,T24,I6,T33,E12.4,2x,E12.4,T60,F8.3)') & 909 iter, nmo_converged, max_norm, min_norm, t2 - t1 910 END IF 911 t1 = m_walltime() 912 913 END DO ! iter 914 915 DEALLOCATE (ritz_coeff) 916 DEALLOCATE (iconv) 917 DEALLOCATE (inotconv) 918 DEALLOCATE (vnorm) 919 920 CALL timestop(handle) 921 922 END SUBROUTINE generate_extended_space_sparse 923 924! ************************************************************************************************** 925 926! ************************************************************************************************** 927!> \brief ... 928!> \param s_block ... 929!> \param h_block ... 930!> \param v_block ... 931!> \param w_block ... 932!> \param evals ... 933!> \param ndim ... 934! ************************************************************************************************** 935 SUBROUTINE reduce_extended_space(s_block, h_block, v_block, w_block, evals, ndim) 936 937 TYPE(cp_fm_type), POINTER :: s_block, h_block, v_block, w_block 938 REAL(dp), DIMENSION(:) :: evals 939 INTEGER :: ndim 940 941 CHARACTER(len=*), PARAMETER :: routineN = 'reduce_extended_space', & 942 routineP = moduleN//':'//routineN 943 944 INTEGER :: handle, info 945 946 CALL timeset(routineN, handle) 947 948 CALL cp_fm_to_fm(s_block, w_block) 949 CALL cp_fm_cholesky_decompose(s_block, info_out=info) 950 IF (info == 0) THEN 951 CALL cp_fm_triangular_invert(s_block) 952 CALL cp_fm_cholesky_restore(H_block, ndim, S_block, w_block, "MULTIPLY", pos="RIGHT") 953 CALL cp_fm_cholesky_restore(w_block, ndim, S_block, H_block, "MULTIPLY", pos="LEFT", transa="T") 954 CALL choose_eigv_solver(H_block, w_block, evals) 955 CALL cp_fm_cholesky_restore(w_block, ndim, S_block, v_block, "MULTIPLY") 956 ELSE 957! S^(-1/2) 958 CALL cp_fm_power(w_block, s_block, -0.5_dp, 1.0E-5_dp, info) 959 CALL cp_fm_to_fm(w_block, s_block) 960 CALL cp_gemm('N', 'N', ndim, ndim, ndim, 1.0_dp, H_block, s_block, 0.0_dp, w_block) 961 CALL cp_gemm('N', 'N', ndim, ndim, ndim, 1.0_dp, s_block, w_block, 0.0_dp, H_block) 962 CALL choose_eigv_solver(H_block, w_block, evals) 963 CALL cp_gemm('N', 'N', ndim, ndim, ndim, 1.0_dp, s_block, w_block, 0.0_dp, v_block) 964 END IF 965 966 CALL timestop(handle) 967 968 END SUBROUTINE reduce_extended_space 969 970END MODULE qs_scf_block_davidson 971