35 USE dbcsr_api,
ONLY: &
36 dbcsr_add, dbcsr_copy, dbcsr_get_block_p, dbcsr_get_info, dbcsr_iterator_blocks_left, &
37 dbcsr_iterator_next_block, dbcsr_iterator_start, dbcsr_iterator_stop, dbcsr_iterator_type, &
38 dbcsr_p_type, dbcsr_release, dbcsr_set, dbcsr_type
42 dbcsr_matrix_colvec_multiply
45 #include "../base/base_uses.f90"
51 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'arnoldi_api'
69 TYPE(dbcsr_p_type),
DIMENSION(:) :: matrix
76 IF (control%generalized_ev)
THEN
77 CALL arnoldi_generalized_ev(matrix, arnoldi_data)
79 CALL arnoldi_normal_ev(matrix, arnoldi_data)
99 SUBROUTINE arnoldi_normal_ev(matrix, arnoldi_data)
100 TYPE(dbcsr_p_type),
DIMENSION(:) :: matrix
103 CHARACTER(LEN=*),
PARAMETER :: routinen =
'arnoldi_normal_ev'
105 INTEGER :: handle, i_loop, ncol_local, nrow_local
107 TYPE(dbcsr_type),
POINTER :: restart_vec
110 NULLIFY (restart_vec)
111 CALL timeset(routinen, handle)
115 CALL dbcsr_copy(vectors%result_vec, vectors%input_vec)
121 CALL dbcsr_get_info(matrix=vectors%input_vec, nfullrows_local=nrow_local, nfullcols_local=ncol_local)
122 control%local_comp = ncol_local > 0 .AND. nrow_local > 0
126 IF (.NOT. control%iram .OR. i_loop == 0)
THEN
145 IF (.NOT.
ASSOCIATED(restart_vec))
ALLOCATE (restart_vec)
149 IF (control%converged)
EXIT
153 CALL dbcsr_release(vectors%input_vec)
154 CALL dbcsr_release(vectors%result_vec)
155 CALL dbcsr_release(vectors%rep_col_vec)
156 CALL dbcsr_release(vectors%rep_row_vec)
157 CALL dbcsr_release(restart_vec)
158 DEALLOCATE (restart_vec)
159 CALL timestop(handle)
161 END SUBROUTINE arnoldi_normal_ev
179 SUBROUTINE arnoldi_generalized_ev(matrix, arnoldi_data)
180 TYPE(dbcsr_p_type),
DIMENSION(:) :: matrix
183 CHARACTER(LEN=*),
PARAMETER :: routinen =
'arnoldi_generalized_ev'
185 INTEGER :: handle, i_loop, ncol_local, nrow_local
187 TYPE(dbcsr_p_type),
ALLOCATABLE,
DIMENSION(:) :: matrix_arnoldi
188 TYPE(dbcsr_type),
TARGET :: a_rho_b
191 CALL timeset(routinen, handle)
192 ALLOCATE (matrix_arnoldi(2))
194 matrix_arnoldi(1)%matrix => a_rho_b
195 matrix_arnoldi(2)%matrix => matrix(2)%matrix
199 CALL dbcsr_copy(vectors%result_vec, vectors%input_vec)
205 CALL dbcsr_get_info(matrix=vectors%input_vec, nfullrows_local=nrow_local, nfullcols_local=ncol_local)
206 control%local_comp = ncol_local > 0 .AND. nrow_local > 0
209 IF (i_loop == 0)
THEN
227 IF (control%converged)
EXIT
231 CALL dbcsr_release(vectors%input_vec)
232 CALL dbcsr_release(vectors%result_vec)
233 CALL dbcsr_release(vectors%rep_col_vec)
234 CALL dbcsr_release(vectors%rep_row_vec)
235 CALL dbcsr_release(a_rho_b)
236 DEALLOCATE (matrix_arnoldi)
238 CALL timestop(handle)
240 END SUBROUTINE arnoldi_generalized_ev
254 TYPE(dbcsr_type),
INTENT(INOUT),
TARGET :: matrix_a
255 REAL(kind=
dp),
INTENT(OUT) :: max_ev, min_ev
256 LOGICAL,
INTENT(OUT) :: converged
257 REAL(kind=
dp),
INTENT(IN) :: threshold
258 INTEGER,
INTENT(IN) :: max_iter
260 CHARACTER(LEN=*),
PARAMETER :: routinen =
'arnoldi_extremal'
262 INTEGER :: handle, max_iter_internal, nrestarts
264 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: arnoldi_matrices
266 CALL timeset(routinen, handle)
270 IF (.true.) max_iter_internal = 16
271 IF (threshold <= 1.0e-3_dp) max_iter_internal = 32
272 IF (threshold <= 1.0e-4_dp) max_iter_internal = 64
275 nrestarts = max_iter/max_iter_internal
277 ALLOCATE (arnoldi_matrices(1))
278 arnoldi_matrices(1)%matrix => matrix_a
280 threshold=threshold, selection_crit=1, nval_request=2, nrestarts=nrestarts, &
281 generalized_ev=.false., iram=.true.)
287 DEALLOCATE (arnoldi_matrices)
289 CALL timestop(handle)
303 TYPE(dbcsr_type),
INTENT(IN),
TARGET :: matrix_a
304 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: vec_x
305 TYPE(dbcsr_type),
INTENT(IN),
OPTIONAL,
TARGET :: matrix_p
306 LOGICAL,
INTENT(OUT) :: converged
307 REAL(kind=
dp),
INTENT(IN) :: threshold
308 INTEGER,
INTENT(IN) :: max_iter
310 CHARACTER(LEN=*),
PARAMETER :: routinen =
'arnoldi_conjugate_gradient'
312 INTEGER :: handle, i, j, nb, nloc, no
313 INTEGER,
DIMENSION(:),
POINTER :: rb_offset, rb_size
314 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: xvec
317 TYPE(dbcsr_iterator_type) :: dbcsr_iter
318 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: arnoldi_matrices
319 TYPE(dbcsr_type),
TARGET :: x
322 CALL timeset(routinen, handle)
327 CALL dbcsr_copy(vectors%result_vec, vectors%input_vec)
331 CALL dbcsr_copy(x, vectors%input_vec)
333 CALL dbcsr_get_info(x, nfullrows_local=nloc, row_blk_size=rb_size, row_blk_offset=rb_offset)
335 CALL dbcsr_iterator_start(dbcsr_iter, x)
336 DO WHILE (dbcsr_iterator_blocks_left(dbcsr_iter))
337 CALL dbcsr_iterator_next_block(dbcsr_iter, i, j, xvec)
340 xvec(1:nb, 1) = vec_x(no:no + nb - 1)
342 CALL dbcsr_iterator_stop(dbcsr_iter)
345 ALLOCATE (arnoldi_matrices(3))
346 arnoldi_matrices(1)%matrix => matrix_a
347 IF (
PRESENT(matrix_p))
THEN
348 arnoldi_matrices(2)%matrix => matrix_p
350 NULLIFY (arnoldi_matrices(2)%matrix)
352 arnoldi_matrices(3)%matrix => x
354 threshold=threshold, selection_crit=1, nval_request=1, nrestarts=0, &
355 generalized_ev=.false., iram=.false.)
357 CALL conjugate_gradient(my_arnoldi, arnoldi_matrices, vectors)
362 CALL dbcsr_iterator_start(dbcsr_iter, x)
363 DO WHILE (dbcsr_iterator_blocks_left(dbcsr_iter))
364 CALL dbcsr_iterator_next_block(dbcsr_iter, i, j, xvec)
367 vec_x(no:no + nb - 1) = xvec(1:nb, 1)
369 CALL dbcsr_iterator_stop(dbcsr_iter)
371 CALL control%mp_group%sum(vec_x)
373 CALL dbcsr_release(x)
374 CALL dbcsr_release(vectors%input_vec)
375 CALL dbcsr_release(vectors%result_vec)
376 CALL dbcsr_release(vectors%rep_col_vec)
377 CALL dbcsr_release(vectors%rep_row_vec)
380 DEALLOCATE (arnoldi_matrices)
382 CALL timestop(handle)
392 SUBROUTINE conjugate_gradient(arnoldi_data, arnoldi_matrices, vectors)
394 TYPE(dbcsr_p_type),
DIMENSION(:) :: arnoldi_matrices
398 REAL(kind=
dp) :: alpha, beta, pap, rsnew, rsold
400 TYPE(dbcsr_type) :: apvec, pvec, rvec, zvec
401 TYPE(dbcsr_type),
POINTER :: amat, pmat, xvec
402 TYPE(mp_comm_type) :: mpgrp, pcgrp
405 control%converged = .false.
406 pcgrp = control%pcol_group
407 mpgrp = control%mp_group
409 NULLIFY (amat, pmat, xvec)
410 amat => arnoldi_matrices(1)%matrix
411 pmat => arnoldi_matrices(2)%matrix
412 xvec => arnoldi_matrices(3)%matrix
414 IF (
ASSOCIATED(pmat))
THEN
416 CALL dbcsr_copy(vectors%input_vec, xvec)
417 CALL dbcsr_matrix_colvec_multiply(pmat, vectors%input_vec, vectors%result_vec, 1.0_dp, &
418 0.0_dp, vectors%rep_row_vec, vectors%rep_col_vec)
419 CALL dbcsr_copy(pvec, vectors%result_vec)
420 CALL dbcsr_copy(vectors%input_vec, pvec)
421 CALL dbcsr_matrix_colvec_multiply(amat, vectors%input_vec, vectors%result_vec, 1.0_dp, &
422 0.0_dp, vectors%rep_row_vec, vectors%rep_col_vec)
423 CALL dbcsr_copy(apvec, vectors%result_vec)
424 CALL dbcsr_copy(rvec, xvec)
425 CALL dbcsr_add(rvec, apvec, 1.0_dp, -1.0_dp)
426 CALL dbcsr_copy(xvec, pvec)
427 CALL dbcsr_copy(vectors%input_vec, rvec)
428 CALL dbcsr_matrix_colvec_multiply(pmat, vectors%input_vec, vectors%result_vec, 1.0_dp, &
429 0.0_dp, vectors%rep_row_vec, vectors%rep_col_vec)
430 CALL dbcsr_copy(zvec, vectors%result_vec)
431 CALL dbcsr_copy(pvec, zvec)
432 rsold = vec_dot_vec(rvec, zvec, mpgrp)
433 DO iter = 1, control%max_iter
434 CALL dbcsr_copy(vectors%input_vec, pvec)
435 CALL dbcsr_matrix_colvec_multiply(amat, vectors%input_vec, vectors%result_vec, 1.0_dp, &
436 0.0_dp, vectors%rep_row_vec, vectors%rep_col_vec)
437 CALL dbcsr_copy(apvec, vectors%result_vec)
439 pap = vec_dot_vec(pvec, apvec, mpgrp)
440 IF (abs(pap) < 1.e-24_dp)
THEN
446 CALL dbcsr_add(xvec, pvec, 1.0_dp, alpha)
447 CALL dbcsr_add(rvec, apvec, 1.0_dp, -alpha)
448 rsnew = vec_dot_vec(rvec, rvec, mpgrp)
449 IF (sqrt(rsnew) < control%threshold)
EXIT
450 cpassert(alpha /= 0.0_dp)
452 CALL dbcsr_copy(vectors%input_vec, rvec)
453 CALL dbcsr_matrix_colvec_multiply(pmat, vectors%input_vec, vectors%result_vec, 1.0_dp, &
454 0.0_dp, vectors%rep_row_vec, vectors%rep_col_vec)
455 CALL dbcsr_copy(zvec, vectors%result_vec)
456 rsnew = vec_dot_vec(rvec, zvec, mpgrp)
458 CALL dbcsr_add(pvec, zvec, beta, 1.0_dp)
461 IF (sqrt(rsnew) < control%threshold) control%converged = .true.
462 CALL dbcsr_release(zvec)
463 CALL dbcsr_release(pvec)
464 CALL dbcsr_release(rvec)
465 CALL dbcsr_release(apvec)
468 CALL dbcsr_copy(pvec, xvec)
469 CALL dbcsr_copy(rvec, xvec)
470 CALL dbcsr_set(xvec, 0.0_dp)
472 rsold = vec_dot_vec(rvec, rvec, mpgrp)
473 DO iter = 1, control%max_iter
474 CALL dbcsr_copy(vectors%input_vec, pvec)
475 CALL dbcsr_matrix_colvec_multiply(amat, vectors%input_vec, vectors%result_vec, 1.0_dp, &
476 0.0_dp, vectors%rep_row_vec, vectors%rep_col_vec)
477 CALL dbcsr_copy(apvec, vectors%result_vec)
478 pap = vec_dot_vec(pvec, apvec, mpgrp)
479 IF (abs(pap) < 1.e-24_dp)
THEN
484 CALL dbcsr_add(xvec, pvec, 1.0_dp, alpha)
485 CALL dbcsr_add(rvec, apvec, 1.0_dp, -alpha)
486 rsnew = vec_dot_vec(rvec, rvec, mpgrp)
487 IF (sqrt(rsnew) < control%threshold)
EXIT
488 cpassert(alpha /= 0.0_dp)
490 CALL dbcsr_add(pvec, rvec, beta, 1.0_dp)
493 IF (sqrt(rsnew) < control%threshold) control%converged = .true.
494 CALL dbcsr_release(pvec)
495 CALL dbcsr_release(rvec)
496 CALL dbcsr_release(apvec)
499 END SUBROUTINE conjugate_gradient
508 FUNCTION vec_dot_vec(avec, bvec, mpgrp)
RESULT(adotb)
509 TYPE(dbcsr_type) :: avec, bvec
510 TYPE(mp_comm_type),
INTENT(IN) :: mpgrp
511 REAL(kind=
dp) :: adotb
515 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: av, bv
516 TYPE(dbcsr_iterator_type) :: dbcsr_iter
519 CALL dbcsr_iterator_start(dbcsr_iter, avec)
520 DO WHILE (dbcsr_iterator_blocks_left(dbcsr_iter))
521 CALL dbcsr_iterator_next_block(dbcsr_iter, i, j, av)
522 CALL dbcsr_get_block_p(bvec, i, j, bv, found)
523 IF (found .AND.
SIZE(bv) > 0)
THEN
524 adotb = adotb + dot_product(av(:, 1), bv(:, 1))
527 CALL dbcsr_iterator_stop(dbcsr_iter)
528 CALL mpgrp%sum(adotb)
530 END FUNCTION vec_dot_vec
arnoldi iteration using dbcsr
subroutine, public arnoldi_extremal(matrix_a, max_ev, min_ev, converged, threshold, max_iter)
simple wrapper to estimate extremal eigenvalues with arnoldi, using the old lanczos interface this hi...
subroutine, public arnoldi_conjugate_gradient(matrix_a, vec_x, matrix_p, converged, threshold, max_iter)
Wrapper for conjugated gradient algorithm for Ax=b.
subroutine, public arnoldi_ev(matrix, arnoldi_data)
Driver routine for different arnoldi eigenvalue methods the selection which one is to be taken is mad...
The methods which allow to analyze and manipulate the arnoldi procedure The main routine and this sho...
subroutine, public select_evals(arnoldi_data)
perform the selection of eigenvalues, fills the selected_ind array
subroutine, public setup_arnoldi_data(arnoldi_data, matrix, max_iter, threshold, selection_crit, nval_request, nrestarts, generalized_ev, iram)
This routine sets the environment for the arnoldi iteration and the krylov subspace creation....
complex(real_8) function, public get_selected_ritz_val(ar_data, ind)
get a single specific Ritz value from the set of selected
subroutine, public get_selected_ritz_vector(arnoldi_data, ind, matrix, vector)
Deallocate the data in arnoldi_data.
subroutine, public deallocate_arnoldi_data(arnoldi_data)
Deallocate the data in arnoldi_data.
logical function, public arnoldi_is_converged(ar_data)
Find out whether the method with the current search criterion is converged.
subroutine, public set_arnoldi_initial_vector(ar_data, vector)
...
integer function, public get_nrestart(arnoldi_data)
returns the number of restarts allowed for arnoldi
methods for arnoldi iteration
subroutine, public arnoldi_init(matrix, vectors, arnoldi_data)
Interface for the initialization of the arnoldi subspace creation currently it can only setup a rando...
subroutine, public gev_update_data(matrix, matrix_arnoldi, vectors, arnoldi_data)
in the generalized eigenvalue the matrix depende on the projection therefore the outer loop has to bu...
subroutine, public gev_build_subspace(matrix, vectors, arnoldi_data)
here the iterations are performed and the krylov space for the generalized eigenvalue problem is crea...
subroutine, public compute_evals(arnoldi_data)
Interface to compute the eigenvalues of a nonsymmetric matrix This is only the serial version.
subroutine, public gev_arnoldi_init(matrix, matrix_arnoldi, vectors, arnoldi_data)
Interface for the initialization of the arnoldi subspace creation for the generalized eigenvalue prob...
subroutine, public build_subspace(matrix, vectors, arnoldi_data)
here the iterations are performed and the krylov space is constructed
subroutine, public arnoldi_iram(arnoldi_data)
Interface for the routine calcualting the implicit restarts Currently all based on lapack.
collection of types used in arnoldi
type(arnoldi_control_type) function, pointer, public get_control(ar_data)
...
operations for skinny matrices/vectors expressed in dbcsr form
subroutine, public create_replicated_row_vec_from_matrix(dbcsr_vec, matrix, nrow)
creates a row vector like object whose blocks can be replicated along the processor col and has the s...
subroutine, public create_col_vec_from_matrix(dbcsr_vec, matrix, ncol)
creates a dbcsr col vector like object which lives on proc_col 0 and has the same row dist as the tem...
subroutine, public create_replicated_col_vec_from_matrix(dbcsr_vec, matrix, ncol)
creates a col vector like object whose blocks can be replicated along the processor row and has the s...
Defines the basic variable types.
integer, parameter, public dp
Interface to the message passing library MPI.