LCOV - code coverage report
Current view: top level - src/arnoldi - arnoldi_data_methods.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:71c3ab0) Lines: 87.8 % 196 172
Test Date: 2026-07-25 06:35:44 Functions: 88.2 % 17 15

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief The methods which allow to analyze and manipulate the arnoldi procedure
      10              : !>        The main routine and this should eb the only public access point for the method
      11              : !> \par History
      12              : !>       2014.09 created [Florian Schiffmann]
      13              : !>       2023.12 Removed support for single-precision [Ole Schuett]
      14              : !>       2024.12 Removed support for complex input matrices [Ole Schuett]
      15              : !> \author Florian Schiffmann
      16              : ! **************************************************************************************************
      17              : MODULE arnoldi_data_methods
      18              :    USE arnoldi_types,                   ONLY: &
      19              :         arnoldi_control_type, arnoldi_data_type, arnoldi_env_type, get_control, get_data, &
      20              :         get_evals, get_sel_ind, set_control, set_data
      21              :    USE arnoldi_vector,                  ONLY: create_col_vec_from_matrix
      22              :    USE cp_dbcsr_api,                    ONLY: &
      23              :         dbcsr_distribution_get, dbcsr_distribution_type, dbcsr_get_data_p, dbcsr_get_info, &
      24              :         dbcsr_get_matrix_type, dbcsr_mp_grid_setup, dbcsr_p_type, dbcsr_release, dbcsr_type, &
      25              :         dbcsr_type_symmetric
      26              :    USE kinds,                           ONLY: dp
      27              :    USE util,                            ONLY: sort
      28              : #include "../base/base_uses.f90"
      29              : 
      30              :    IMPLICIT NONE
      31              : 
      32              :    PRIVATE
      33              : 
      34              :    PUBLIC :: select_evals, get_selected_ritz_val, arnoldi_is_converged, &
      35              :              arnoldi_env_type, get_nrestart, set_arnoldi_initial_vector, &
      36              :              setup_arnoldi_env, deallocate_arnoldi_env, get_selected_ritz_vector
      37              : 
      38              : CONTAINS
      39              : 
      40              : ! **************************************************************************************************
      41              : !> \brief This routine sets the environment for the arnoldi iteration and
      42              : !>        the krylov subspace creation. All simulation parameters have to be given
      43              : !>        at this stage so the rest can run fully automated
      44              : !>        In addition, this routine allocates the data necessary for
      45              : !> \param arnoldi_env this type which gets filled with information and on output contains all
      46              : !>                    information necessary to extract whatever the user desires
      47              : !> \param matrix vector of matrices, only the first gets used to get some dimensions
      48              : !>        and parallel information needed later on
      49              : !> \param max_iter maximum dimension of the krylov subspace
      50              : !> \param threshold convergence threshold, this is used for both subspace and eigenval
      51              : !> \param selection_crit integer defining according to which criterion the
      52              : !>        eigenvalues are selected for the subspace
      53              : !> \param nval_request for some sel_crit useful, how many eV to select
      54              : !> \param nrestarts ...
      55              : !> \param generalized_ev ...
      56              : !> \param iram ...
      57              : ! **************************************************************************************************
      58       145343 :    SUBROUTINE setup_arnoldi_env(arnoldi_env, matrix, max_iter, threshold, selection_crit, &
      59              :                                 nval_request, nrestarts, generalized_ev, iram)
      60              :       TYPE(arnoldi_env_type)                             :: arnoldi_env
      61              :       TYPE(dbcsr_p_type), DIMENSION(:)                   :: matrix
      62              :       INTEGER                                            :: max_iter
      63              :       REAL(dp)                                           :: threshold
      64              :       INTEGER                                            :: selection_crit, nval_request, nrestarts
      65              :       LOGICAL                                            :: generalized_ev, iram
      66              : 
      67              :       CALL setup_arnoldi_control(arnoldi_env, matrix, max_iter, threshold, selection_crit, &
      68       145343 :                                  nval_request, nrestarts, generalized_ev, iram)
      69              : 
      70       145343 :       CALL setup_arnoldi_data(arnoldi_env, matrix, max_iter)
      71              : 
      72       145343 :    END SUBROUTINE setup_arnoldi_env
      73              : 
      74              : ! **************************************************************************************************
      75              : !> \brief Creates the data type for arnoldi, see above for details
      76              : !> \param arnoldi_env ...
      77              : !> \param matrix ...
      78              : !> \param max_iter ...
      79              : ! **************************************************************************************************
      80       145343 :    SUBROUTINE setup_arnoldi_data(arnoldi_env, matrix, max_iter)
      81              :       TYPE(arnoldi_env_type)                             :: arnoldi_env
      82              :       TYPE(dbcsr_p_type), DIMENSION(:)                   :: matrix
      83              :       INTEGER                                            :: max_iter
      84              : 
      85              :       INTEGER                                            :: nrow_local
      86              :       TYPE(arnoldi_data_type), POINTER                   :: ar_data
      87              : 
      88       145343 :       ALLOCATE (ar_data)
      89       145343 :       CALL dbcsr_get_info(matrix=matrix(1)%matrix, nfullrows_local=nrow_local)
      90       384711 :       ALLOCATE (ar_data%f_vec(nrow_local))
      91       239368 :       ALLOCATE (ar_data%x_vec(nrow_local))
      92       581372 :       ALLOCATE (ar_data%Hessenberg(max_iter + 1, max_iter))
      93       530054 :       ALLOCATE (ar_data%local_history(nrow_local, max_iter))
      94              : 
      95       436029 :       ALLOCATE (ar_data%evals(max_iter))
      96       581372 :       ALLOCATE (ar_data%revec(max_iter, max_iter))
      97              : 
      98       145343 :       CALL set_data(arnoldi_env, ar_data)
      99              : 
     100       145343 :    END SUBROUTINE setup_arnoldi_data
     101              : 
     102              : ! **************************************************************************************************
     103              : !> \brief Creates the control type for arnoldi, see above for details
     104              : !> \param arnoldi_env ...
     105              : !> \param matrix ...
     106              : !> \param max_iter ...
     107              : !> \param threshold ...
     108              : !> \param selection_crit ...
     109              : !> \param nval_request ...
     110              : !> \param nrestarts ...
     111              : !> \param generalized_ev ...
     112              : !> \param iram ...
     113              : ! **************************************************************************************************
     114       145343 :    SUBROUTINE setup_arnoldi_control(arnoldi_env, matrix, max_iter, threshold, selection_crit, &
     115              :                                     nval_request, nrestarts, generalized_ev, iram)
     116              :       TYPE(arnoldi_env_type)                             :: arnoldi_env
     117              :       TYPE(dbcsr_p_type), DIMENSION(:)                   :: matrix
     118              :       INTEGER                                            :: max_iter
     119              :       REAL(dp)                                           :: threshold
     120              :       INTEGER                                            :: selection_crit, nval_request, nrestarts
     121              :       LOGICAL                                            :: generalized_ev, iram
     122              : 
     123              :       INTEGER                                            :: group_handle, pcol_handle
     124              :       LOGICAL                                            :: subgroups_defined
     125              :       TYPE(arnoldi_control_type), POINTER                :: control
     126              :       TYPE(dbcsr_distribution_type)                      :: distri
     127              : 
     128            0 :       ALLOCATE (control)
     129              :       ! Fill the information which will later control the arnoldi method and allow synchronization.
     130       145343 :       CALL dbcsr_get_info(matrix=matrix(1)%matrix, distribution=distri)
     131       145343 :       CALL dbcsr_mp_grid_setup(distri)
     132              :       CALL dbcsr_distribution_get(distri, &
     133              :                                   group=group_handle, &
     134              :                                   mynode=control%myproc, &
     135              :                                   subgroups_defined=subgroups_defined, &
     136       145343 :                                   pcol_group=pcol_handle)
     137              : 
     138       145343 :       CALL control%mp_group%set_handle(group_handle)
     139       145343 :       CALL control%pcol_group%set_handle(pcol_handle)
     140              : 
     141       145343 :       IF (.NOT. subgroups_defined) THEN
     142            0 :          CPABORT("arnoldi only with subgroups")
     143              :       END IF
     144              : 
     145       145343 :       control%symmetric = .FALSE.
     146              :       ! Will need a fix for complex because there it has to be hermitian
     147       145343 :       IF (SIZE(matrix) == 1) THEN
     148       141114 :          control%symmetric = dbcsr_get_matrix_type(matrix(1)%matrix) == dbcsr_type_symmetric
     149              :       END IF
     150              : 
     151              :       ! Set the control parameters
     152       145343 :       control%max_iter = max_iter
     153       145343 :       control%current_step = 0
     154       145343 :       control%selection_crit = selection_crit
     155       145343 :       control%nval_req = nval_request
     156       145343 :       control%threshold = threshold
     157       145343 :       control%converged = .FALSE.
     158       145343 :       control%has_initial_vector = .FALSE.
     159       145343 :       control%iram = iram
     160       145343 :       control%nrestart = nrestarts
     161       145343 :       control%generalized_ev = generalized_ev
     162              : 
     163       145343 :       IF (control%nval_req > 1 .AND. control%nrestart > 0 .AND. .NOT. control%iram) THEN
     164              :          CALL cp_abort(__LOCATION__, 'with more than one eigenvalue requested '// &
     165            0 :                        'internal restarting with a previous EVEC is a bad idea, set IRAM or nrestsart=0')
     166              :       END IF
     167              : 
     168              :       ! some checks for the generalized EV mode
     169       145343 :       IF (control%generalized_ev .AND. selection_crit == 1) THEN
     170              :          CALL cp_abort(__LOCATION__, &
     171            0 :                        'generalized ev can only highest OR lowest EV')
     172              :       END IF
     173       145343 :       IF (control%generalized_ev .AND. nval_request /= 1) THEN
     174              :          CALL cp_abort(__LOCATION__, &
     175            0 :                        'generalized ev can only compute one EV at the time')
     176              :       END IF
     177       145343 :       IF (control%generalized_ev .AND. control%nrestart == 0) THEN
     178              :          CALL cp_abort(__LOCATION__, &
     179            0 :                        'outer loops are mandatory for generalized EV, set nrestart appropriatly')
     180              :       END IF
     181       145343 :       IF (SIZE(matrix) /= 2 .AND. control%generalized_ev) THEN
     182              :          CALL cp_abort(__LOCATION__, &
     183            0 :                        'generalized ev needs exactly two matrices as input (2nd is the metric)')
     184              :       END IF
     185              : 
     186       436029 :       ALLOCATE (control%selected_ind(max_iter))
     187       145343 :       CALL set_control(arnoldi_env, control)
     188              : 
     189       290686 :    END SUBROUTINE setup_arnoldi_control
     190              : 
     191              : ! **************************************************************************************************
     192              : !> \brief ...
     193              : !> \param arnoldi_env ...
     194              : !> \param ind ...
     195              : !> \param matrix ...
     196              : !> \param vector ...
     197              : ! **************************************************************************************************
     198       150236 :    SUBROUTINE get_selected_ritz_vector(arnoldi_env, ind, matrix, vector)
     199              :       TYPE(arnoldi_env_type)                             :: arnoldi_env
     200              :       INTEGER                                            :: ind
     201              :       TYPE(dbcsr_type)                                   :: matrix, vector
     202              : 
     203       150236 :       COMPLEX(dp), ALLOCATABLE, DIMENSION(:)             :: ritz_v
     204              :       INTEGER                                            :: i, myind, sspace_size, vsize
     205       150236 :       INTEGER, DIMENSION(:), POINTER                     :: selected_ind
     206       150236 :       REAL(kind=dp), DIMENSION(:), POINTER               :: data_vec
     207              :       TYPE(arnoldi_control_type), POINTER                :: control
     208              :       TYPE(arnoldi_data_type), POINTER                   :: ar_data
     209              : 
     210       300472 :       control => get_control(arnoldi_env)
     211       150236 :       selected_ind => get_sel_ind(arnoldi_env)
     212       150236 :       ar_data => get_data(arnoldi_env)
     213       150236 :       sspace_size = get_subsp_size(arnoldi_env)
     214       150236 :       vsize = SIZE(ar_data%f_vec)
     215       150236 :       myind = selected_ind(ind)
     216       397531 :       ALLOCATE (ritz_v(vsize))
     217       150236 :       ritz_v = CMPLX(0.0, 0.0, dp)
     218              : 
     219       150236 :       CALL dbcsr_release(vector)
     220       150236 :       CALL create_col_vec_from_matrix(vector, matrix, 1)
     221       150236 :       IF (control%local_comp) THEN
     222       682938 :          DO i = 1, sspace_size
     223      9648258 :             ritz_v(:) = ritz_v(:) + ar_data%local_history(:, i)*ar_data%revec(i, myind)
     224              :          END DO
     225        97059 :          data_vec => dbcsr_get_data_p(vector)
     226              :          ! is a bit odd but ritz_v is always complex and matrix type determines where it goes
     227              :          ! again I hope the user knows what is required
     228       979864 :          data_vec(1:vsize) = REAL(ritz_v(1:vsize), KIND=dp)
     229              :       END IF
     230              : 
     231       150236 :       DEALLOCATE (ritz_v)
     232              : 
     233       150236 :    END SUBROUTINE get_selected_ritz_vector
     234              : 
     235              : ! **************************************************************************************************
     236              : !> \brief Deallocate the data in arnoldi_env
     237              : !> \param arnoldi_env ...
     238              : ! **************************************************************************************************
     239       145343 :    SUBROUTINE deallocate_arnoldi_env(arnoldi_env)
     240              :       TYPE(arnoldi_env_type)                             :: arnoldi_env
     241              : 
     242              :       TYPE(arnoldi_control_type), POINTER                :: control
     243              :       TYPE(arnoldi_data_type), POINTER                   :: ar_data
     244              : 
     245       145343 :       ar_data => get_data(arnoldi_env)
     246       145343 :       IF (ASSOCIATED(ar_data%f_vec)) DEALLOCATE (ar_data%f_vec)
     247       145343 :       IF (ASSOCIATED(ar_data%x_vec)) DEALLOCATE (ar_data%x_vec)
     248       145343 :       IF (ASSOCIATED(ar_data%Hessenberg)) DEALLOCATE (ar_data%Hessenberg)
     249       145343 :       IF (ASSOCIATED(ar_data%local_history)) DEALLOCATE (ar_data%local_history)
     250       145343 :       IF (ASSOCIATED(ar_data%evals)) DEALLOCATE (ar_data%evals)
     251       145343 :       IF (ASSOCIATED(ar_data%revec)) DEALLOCATE (ar_data%revec)
     252       145343 :       DEALLOCATE (ar_data)
     253              : 
     254       145343 :       control => get_control(arnoldi_env)
     255       145343 :       DEALLOCATE (control%selected_ind)
     256       145343 :       DEALLOCATE (control)
     257              : 
     258       145343 :    END SUBROUTINE deallocate_arnoldi_env
     259              : 
     260              : ! **************************************************************************************************
     261              : !> \brief perform the selection of eigenvalues, fills the selected_ind array
     262              : !> \param arnoldi_env ...
     263              : ! **************************************************************************************************
     264       146371 :    SUBROUTINE select_evals(arnoldi_env)
     265              :       TYPE(arnoldi_env_type)                             :: arnoldi_env
     266              : 
     267              :       INTEGER                                            :: i, last_el, my_crit, my_ind
     268              :       REAL(dp)                                           :: convergence
     269              :       TYPE(arnoldi_control_type), POINTER                :: control
     270              :       TYPE(arnoldi_data_type), POINTER                   :: ar_data
     271              : 
     272       146371 :       control => get_control(arnoldi_env)
     273       146371 :       ar_data => get_data(arnoldi_env)
     274              : 
     275       146371 :       last_el = control%current_step
     276       146371 :       convergence = REAL(0.0, dp)
     277       146371 :       my_crit = control%selection_crit
     278       146371 :       control%nval_out = MIN(control%nval_req, control%current_step)
     279       136583 :       SELECT CASE (my_crit)
     280              :          ! minimum and maximum real eval
     281              :       CASE (1)
     282       136583 :          CALL index_min_max_real_eval(ar_data%evals, control%current_step, control%selected_ind, control%nval_out)
     283              :          ! n maximum real eval
     284              :       CASE (2)
     285         4457 :          CALL index_nmax_real_eval(ar_data%evals, control%current_step, control%selected_ind, control%nval_out)
     286              :          ! n minimum real eval
     287              :       CASE (3)
     288         5331 :          CALL index_nmin_real_eval(ar_data%evals, control%current_step, control%selected_ind, control%nval_out)
     289              :       CASE DEFAULT
     290       146371 :          CPABORT("unknown selection index")
     291              :       END SELECT
     292              :       ! test whether we are converged
     293       429325 :       DO i = 1, control%nval_out
     294       282954 :          my_ind = control%selected_ind(i)
     295              :          convergence = MAX(convergence, &
     296       429325 :                            ABS(ar_data%revec(last_el, my_ind)*ar_data%Hessenberg(last_el + 1, last_el)))
     297              :       END DO
     298       146371 :       control%converged = convergence < control%threshold
     299              : 
     300       146371 :    END SUBROUTINE select_evals
     301              : 
     302              : ! **************************************************************************************************
     303              : !> \brief set a new selection type, if you notice you didn't like the initial one
     304              : !> \param arnoldi_env ...
     305              : !> \param itype ...
     306              : ! **************************************************************************************************
     307            0 :    SUBROUTINE set_eval_selection(arnoldi_env, itype)
     308              :       TYPE(arnoldi_env_type)                             :: arnoldi_env
     309              :       INTEGER                                            :: itype
     310              : 
     311              :       TYPE(arnoldi_control_type), POINTER                :: control
     312              : 
     313            0 :       control => get_control(arnoldi_env)
     314            0 :       control%selection_crit = itype
     315            0 :    END SUBROUTINE set_eval_selection
     316              : 
     317              : ! **************************************************************************************************
     318              : !> \brief returns the number of restarts allowed for arnoldi
     319              : !> \param arnoldi_env ...
     320              : !> \return ...
     321              : ! **************************************************************************************************
     322       145125 :    FUNCTION get_nrestart(arnoldi_env) RESULT(nrestart)
     323              :       TYPE(arnoldi_env_type)                             :: arnoldi_env
     324              :       INTEGER                                            :: nrestart
     325              : 
     326              :       TYPE(arnoldi_control_type), POINTER                :: control
     327              : 
     328       145125 :       control => get_control(arnoldi_env)
     329       145125 :       nrestart = control%nrestart
     330              : 
     331       145125 :    END FUNCTION get_nrestart
     332              : 
     333              : ! **************************************************************************************************
     334              : !> \brief get the number of eigenvalues matching the search criterion
     335              : !> \param arnoldi_env ...
     336              : !> \return ...
     337              : ! **************************************************************************************************
     338       281448 :    FUNCTION get_nval_out(arnoldi_env) RESULT(nval_out)
     339              :       TYPE(arnoldi_env_type)                             :: arnoldi_env
     340              :       INTEGER                                            :: nval_out
     341              : 
     342              :       TYPE(arnoldi_control_type), POINTER                :: control
     343              : 
     344       281448 :       control => get_control(arnoldi_env)
     345       281448 :       nval_out = control%nval_out
     346              : 
     347       281448 :    END FUNCTION get_nval_out
     348              : 
     349              : ! **************************************************************************************************
     350              : !> \brief get dimension of the krylov space. Can be less than max_iter if subspace converged early
     351              : !> \param arnoldi_env ...
     352              : !> \return ...
     353              : ! **************************************************************************************************
     354       150236 :    FUNCTION get_subsp_size(arnoldi_env) RESULT(current_step)
     355              :       TYPE(arnoldi_env_type)                             :: arnoldi_env
     356              :       INTEGER                                            :: current_step
     357              : 
     358              :       TYPE(arnoldi_control_type), POINTER                :: control
     359              : 
     360       150236 :       control => get_control(arnoldi_env)
     361       150236 :       current_step = control%current_step
     362              : 
     363       150236 :    END FUNCTION get_subsp_size
     364              : 
     365              : ! **************************************************************************************************
     366              : !> \brief Find out whether the method with the current search criterion is converged
     367              : !> \param arnoldi_env ...
     368              : !> \return ...
     369              : ! **************************************************************************************************
     370       136541 :    FUNCTION arnoldi_is_converged(arnoldi_env) RESULT(converged)
     371              :       TYPE(arnoldi_env_type)                             :: arnoldi_env
     372              :       LOGICAL                                            :: converged
     373              : 
     374              :       TYPE(arnoldi_control_type), POINTER                :: control
     375              : 
     376       136541 :       control => get_control(arnoldi_env)
     377       136541 :       converged = control%converged
     378              : 
     379       136541 :    END FUNCTION arnoldi_is_converged
     380              : 
     381              : ! **************************************************************************************************
     382              : !> \brief get a single specific Ritz value from the set of selected
     383              : !> \param arnoldi_env ...
     384              : !> \param ind ...
     385              : !> \return ...
     386              : ! **************************************************************************************************
     387       281448 :    FUNCTION get_selected_ritz_val(arnoldi_env, ind) RESULT(eval_out)
     388              :       TYPE(arnoldi_env_type)                             :: arnoldi_env
     389              :       INTEGER                                            :: ind
     390              :       COMPLEX(dp)                                        :: eval_out
     391              : 
     392       281448 :       COMPLEX(dp), DIMENSION(:), POINTER                 :: evals
     393              :       INTEGER                                            :: ev_ind
     394       281448 :       INTEGER, DIMENSION(:), POINTER                     :: selected_ind
     395              : 
     396       281448 :       IF (ind > get_nval_out(arnoldi_env)) THEN
     397            0 :          CPABORT('outside range of indexed evals')
     398              :       END IF
     399              : 
     400       281448 :       selected_ind => get_sel_ind(arnoldi_env)
     401       281448 :       ev_ind = selected_ind(ind)
     402       281448 :       evals => get_evals(arnoldi_env)
     403       281448 :       eval_out = evals(ev_ind)
     404              : 
     405       281448 :    END FUNCTION get_selected_ritz_val
     406              : 
     407              : ! **************************************************************************************************
     408              : !> \brief Get all Ritz values of the selected set. eval_out has to be allocated
     409              : !>        at least the size of get_neval_out()
     410              : !> \param arnoldi_env ...
     411              : !> \param eval_out ...
     412              : ! **************************************************************************************************
     413            0 :    SUBROUTINE get_all_selected_ritz_val(arnoldi_env, eval_out)
     414              :       TYPE(arnoldi_env_type)                             :: arnoldi_env
     415              :       COMPLEX(dp), DIMENSION(:)                          :: eval_out
     416              : 
     417            0 :       COMPLEX(dp), DIMENSION(:), POINTER                 :: evals
     418              :       INTEGER                                            :: ev_ind, ind
     419            0 :       INTEGER, DIMENSION(:), POINTER                     :: selected_ind
     420              : 
     421            0 :       NULLIFY (evals)
     422            0 :       IF (SIZE(eval_out) < get_nval_out(arnoldi_env)) THEN
     423            0 :          CPABORT('array for eval output too small')
     424              :       END IF
     425            0 :       selected_ind => get_sel_ind(arnoldi_env)
     426              : 
     427            0 :       evals => get_evals(arnoldi_env)
     428              : 
     429            0 :       DO ind = 1, get_nval_out(arnoldi_env)
     430            0 :          ev_ind = selected_ind(ind)
     431            0 :          eval_out(ind) = evals(ev_ind)
     432              :       END DO
     433              : 
     434            0 :    END SUBROUTINE get_all_selected_ritz_val
     435              : 
     436              : ! **************************************************************************************************
     437              : !> \brief ...
     438              : !> \param arnoldi_env ...
     439              : !> \param vector ...
     440              : ! **************************************************************************************************
     441         9792 :    SUBROUTINE set_arnoldi_initial_vector(arnoldi_env, vector)
     442              :       TYPE(arnoldi_env_type)                             :: arnoldi_env
     443              :       TYPE(dbcsr_type)                                   :: vector
     444              : 
     445              :       INTEGER                                            :: ncol_local, nrow_local
     446         4896 :       REAL(kind=dp), DIMENSION(:), POINTER               :: data_vec
     447              :       TYPE(arnoldi_control_type), POINTER                :: control
     448              :       TYPE(arnoldi_data_type), POINTER                   :: ar_data
     449              : 
     450         9792 :       control => get_control(arnoldi_env)
     451         4896 :       control%has_initial_vector = .TRUE.
     452         4896 :       ar_data => get_data(arnoldi_env)
     453              : 
     454         4896 :       CALL dbcsr_get_info(matrix=vector, nfullrows_local=nrow_local, nfullcols_local=ncol_local)
     455         4896 :       data_vec => dbcsr_get_data_p(vector)
     456       151293 :       IF (nrow_local*ncol_local > 0) ar_data%f_vec(1:nrow_local) = data_vec(1:nrow_local)
     457              : 
     458         4896 :    END SUBROUTINE set_arnoldi_initial_vector
     459              : 
     460              : !!! Here come the methods handling the selection of eigenvalues and eigenvectors !!!
     461              : !!! If you want a personal method, simply created a Subroutine returning the index
     462              : !!! array selected ind which contains as the first nval_out entries the index of the evals
     463              : 
     464              : ! **************************************************************************************************
     465              : !> \brief ...
     466              : !> \param evals ...
     467              : !> \param current_step ...
     468              : !> \param selected_ind ...
     469              : !> \param neval ...
     470              : ! **************************************************************************************************
     471       136583 :    SUBROUTINE index_min_max_real_eval(evals, current_step, selected_ind, neval)
     472              :       COMPLEX(dp), DIMENSION(:)                          :: evals
     473              :       INTEGER, INTENT(IN)                                :: current_step
     474              :       INTEGER, DIMENSION(:)                              :: selected_ind
     475              :       INTEGER                                            :: neval
     476              : 
     477              :       INTEGER                                            :: i
     478       273166 :       INTEGER, DIMENSION(current_step)                   :: indexing
     479       273166 :       REAL(dp), DIMENSION(current_step)                  :: tmp_array
     480              : 
     481       136583 :       neval = 0
     482      4522855 :       selected_ind = 0
     483       776886 :       tmp_array(1:current_step) = REAL(evals(1:current_step), dp)
     484       136583 :       CALL sort(tmp_array, current_step, indexing)
     485       136583 :       DO i = 1, current_step
     486       136583 :          IF (ABS(AIMAG(evals(indexing(i)))) < EPSILON(0.0_dp)) THEN
     487       136583 :             selected_ind(1) = indexing(i)
     488       136583 :             neval = neval + 1
     489       136583 :             EXIT
     490              :          END IF
     491              :       END DO
     492       136583 :       DO i = current_step, 1, -1
     493       136583 :          IF (ABS(AIMAG(evals(indexing(i)))) < EPSILON(0.0_dp)) THEN
     494       136583 :             selected_ind(2) = indexing(i)
     495       136583 :             neval = neval + 1
     496       136583 :             EXIT
     497              :          END IF
     498              :       END DO
     499              : 
     500       136583 :    END SUBROUTINE index_min_max_real_eval
     501              : 
     502              : ! **************************************************************************************************
     503              : !> \brief ...
     504              : !> \param evals ...
     505              : !> \param current_step ...
     506              : !> \param selected_ind ...
     507              : !> \param neval ...
     508              : ! **************************************************************************************************
     509         4457 :    SUBROUTINE index_nmax_real_eval(evals, current_step, selected_ind, neval)
     510              :       COMPLEX(dp), DIMENSION(:)                          :: evals
     511              :       INTEGER, INTENT(IN)                                :: current_step
     512              :       INTEGER, DIMENSION(:)                              :: selected_ind
     513              :       INTEGER                                            :: neval
     514              : 
     515              :       INTEGER                                            :: i, nlimit
     516         8914 :       INTEGER, DIMENSION(current_step)                   :: indexing
     517         8914 :       REAL(dp), DIMENSION(current_step)                  :: tmp_array
     518              : 
     519         4457 :       nlimit = neval; neval = 0
     520        93597 :       selected_ind = 0
     521        22758 :       tmp_array(1:current_step) = REAL(evals(1:current_step), dp)
     522         4457 :       CALL sort(tmp_array, current_step, indexing)
     523         4457 :       DO i = 1, current_step
     524         8914 :          IF (ABS(AIMAG(evals(indexing(current_step + 1 - i)))) < EPSILON(0.0_dp)) THEN
     525         4457 :             selected_ind(i) = indexing(current_step + 1 - i)
     526         4457 :             neval = neval + 1
     527         4457 :             IF (neval == nlimit) EXIT
     528              :          END IF
     529              :       END DO
     530              : 
     531         4457 :    END SUBROUTINE index_nmax_real_eval
     532              : 
     533              : ! **************************************************************************************************
     534              : !> \brief ...
     535              : !> \param evals ...
     536              : !> \param current_step ...
     537              : !> \param selected_ind ...
     538              : !> \param neval ...
     539              : ! **************************************************************************************************
     540         5331 :    SUBROUTINE index_nmin_real_eval(evals, current_step, selected_ind, neval)
     541              :       COMPLEX(dp), DIMENSION(:)                          :: evals
     542              :       INTEGER, INTENT(IN)                                :: current_step
     543              :       INTEGER, DIMENSION(:)                              :: selected_ind
     544              :       INTEGER                                            :: neval
     545              : 
     546              :       INTEGER                                            :: i, nlimit
     547        10662 :       INTEGER, DIMENSION(current_step)                   :: indexing
     548        10662 :       REAL(dp), DIMENSION(current_step)                  :: tmp_array
     549              : 
     550         5331 :       nlimit = neval; neval = 0
     551       111951 :       selected_ind = 0
     552        90200 :       tmp_array(1:current_step) = REAL(evals(1:current_step), dp)
     553         5331 :       CALL sort(tmp_array, current_step, indexing)
     554         5331 :       DO i = 1, current_step
     555        10662 :          IF (ABS(AIMAG(evals(indexing(i)))) < EPSILON(0.0_dp)) THEN
     556         5331 :             selected_ind(i) = indexing(i)
     557         5331 :             neval = neval + 1
     558         5331 :             IF (neval == nlimit) EXIT
     559              :          END IF
     560              :       END DO
     561              : 
     562         5331 :    END SUBROUTINE index_nmin_real_eval
     563              : 
     564              : END MODULE arnoldi_data_methods
        

Generated by: LCOV version 2.0-1