23 USE dbcsr_api,
ONLY: &
24 dbcsr_copy, dbcsr_dot, dbcsr_init_p, dbcsr_multiply, dbcsr_p_type, dbcsr_release_p, &
25 dbcsr_scale, dbcsr_set, dbcsr_type, dbcsr_type_no_symmetry
40 #include "./base/base_uses.f90"
47 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qs_ot_eigensolver'
71 matrix_c_fm, preconditioner, eps_gradient, &
72 iter_max, size_ortho_space, silent, ot_settings)
74 TYPE(dbcsr_type),
POINTER :: matrix_h, matrix_s
75 TYPE(cp_fm_type),
INTENT(IN),
OPTIONAL :: matrix_orthogonal_space_fm
76 TYPE(cp_fm_type),
INTENT(IN) :: matrix_c_fm
78 REAL(kind=
dp) :: eps_gradient
79 INTEGER,
INTENT(IN) :: iter_max
80 INTEGER,
INTENT(IN),
OPTIONAL :: size_ortho_space
81 LOGICAL,
INTENT(IN),
OPTIONAL :: silent
82 TYPE(qs_ot_settings_type),
INTENT(IN),
OPTIONAL :: ot_settings
84 CHARACTER(len=*),
PARAMETER :: routinen =
'ot_eigensolver'
85 INTEGER,
PARAMETER :: max_iter_inner_loop = 40
86 REAL(kind=
dp),
PARAMETER :: rone = 1.0_dp, rzero = 0.0_dp
88 INTEGER :: handle, ieigensolver, iter_total, k, n, &
89 ortho_k, ortho_space_k, output_unit
90 LOGICAL :: energy_only, my_silent, ortho
91 REAL(kind=
dp) :: delta, energy
92 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_hc
93 TYPE(dbcsr_type),
POINTER :: matrix_buf1_ortho, matrix_buf2_ortho, &
94 matrix_c, matrix_orthogonal_space, &
95 matrix_os_ortho, matrix_s_ortho
96 TYPE(qs_ot_type),
DIMENSION(:),
POINTER :: qs_ot_env
98 CALL timeset(routinen, handle)
102 IF (
PRESENT(silent))
THEN
120 NULLIFY (matrix_s_ortho)
121 NULLIFY (matrix_os_ortho)
122 NULLIFY (matrix_buf1_ortho)
123 NULLIFY (matrix_buf2_ortho)
124 NULLIFY (matrix_orthogonal_space)
126 ALLOCATE (qs_ot_env(1))
127 ALLOCATE (matrix_hc(1))
128 NULLIFY (matrix_hc(1)%matrix)
129 CALL dbcsr_init_p(matrix_hc(1)%matrix)
130 CALL dbcsr_copy(matrix_hc(1)%matrix, matrix_c,
'matrix_hc')
133 IF (
PRESENT(matrix_orthogonal_space_fm)) ortho = .true.
136 IF (
PRESENT(ot_settings))
THEN
137 qs_ot_env(1)%settings = ot_settings
141 qs_ot_env(1)%settings%ds_min = 0.10_dp
145 ALLOCATE (matrix_orthogonal_space)
147 CALL cp_fm_get_info(matrix_orthogonal_space_fm, ncol_global=ortho_space_k)
149 IF (
PRESENT(size_ortho_space)) ortho_space_k = size_ortho_space
150 ortho_k = ortho_space_k + k
156 CALL qs_ot_allocate(qs_ot_env(1), matrix_s, matrix_c_fm%matrix_struct, ortho_k=ortho_k)
161 CALL dbcsr_init_p(matrix_s_ortho)
162 CALL dbcsr_copy(matrix_s_ortho, matrix_orthogonal_space, name=
"matrix_s_ortho")
164 CALL dbcsr_init_p(matrix_os_ortho)
166 sym=dbcsr_type_no_symmetry)
168 CALL dbcsr_init_p(matrix_buf1_ortho)
170 sym=dbcsr_type_no_symmetry)
172 CALL dbcsr_init_p(matrix_buf2_ortho)
174 sym=dbcsr_type_no_symmetry)
176 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s, matrix_orthogonal_space, &
177 0.0_dp, matrix_s_ortho)
178 CALL dbcsr_multiply(
'T',
'N', rone, matrix_s_ortho, matrix_s_ortho, &
179 rzero, matrix_os_ortho)
182 para_env=qs_ot_env(1)%para_env, blacs_env=qs_ot_env(1)%blacs_env)
184 para_env=qs_ot_env(1)%para_env, blacs_env=qs_ot_env(1)%blacs_env, &
185 upper_to_full=.true.)
187 CALL dbcsr_multiply(
'T',
'N', rone, matrix_s_ortho, matrix_c, &
188 rzero, matrix_buf1_ortho)
189 CALL dbcsr_multiply(
'N',
'N', rone, matrix_os_ortho, matrix_buf1_ortho, &
190 rzero, matrix_buf2_ortho)
191 CALL dbcsr_multiply(
'N',
'N', -rone, matrix_s_ortho, matrix_buf2_ortho, &
195 CALL dbcsr_copy(qs_ot_env(1)%matrix_c0, matrix_c)
196 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s, qs_ot_env(1)%matrix_c0, &
199 CALL make_basis_sv(qs_ot_env(1)%matrix_c0, k, matrix_c, &
200 qs_ot_env(1)%para_env, qs_ot_env(1)%blacs_env)
205 para_env=qs_ot_env(1)%para_env, blacs_env=qs_ot_env(1)%blacs_env)
208 para_env=qs_ot_env(1)%para_env, blacs_env=qs_ot_env(1)%blacs_env)
210 CALL dbcsr_release_p(matrix_buf1_ortho)
211 CALL dbcsr_release_p(matrix_buf2_ortho)
212 CALL dbcsr_release_p(matrix_os_ortho)
213 CALL dbcsr_release_p(matrix_s_ortho)
218 CALL dbcsr_copy(qs_ot_env(1)%matrix_c0, matrix_c)
219 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s, qs_ot_env(1)%matrix_c0, &
220 0.0_dp, qs_ot_env(1)%matrix_sc0)
222 CALL make_basis_sv(qs_ot_env(1)%matrix_c0, k, qs_ot_env(1)%matrix_sc0, &
223 qs_ot_env(1)%para_env, qs_ot_env(1)%blacs_env)
228 energy_only = qs_ot_env(1)%energy_only
231 CALL dbcsr_set(qs_ot_env(1)%matrix_x, 0.0_dp)
232 CALL dbcsr_set(qs_ot_env(1)%matrix_sx, 0.0_dp)
235 CALL qs_ot_get_p(qs_ot_env(1)%matrix_x, qs_ot_env(1)%matrix_sx, qs_ot_env(1))
254 ieigensolver = ieigensolver + 1
255 iter_total = iter_total + 1
258 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_h, matrix_c, &
259 0.0_dp, matrix_hc(1)%matrix)
260 CALL dbcsr_dot(matrix_c, matrix_hc(1)%matrix, energy)
261 IF (.NOT. energy_only)
THEN
262 CALL dbcsr_scale(matrix_hc(1)%matrix, 2.0_dp)
265 qs_ot_env(1)%etotal = energy
266 CALL ot_mini(qs_ot_env, matrix_hc)
267 delta = qs_ot_env(1)%delta
268 energy_only = qs_ot_env(1)%energy_only
270 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, matrix_s, qs_ot_env(1)%matrix_x, &
271 0.0_dp, qs_ot_env(1)%matrix_sx)
273 CALL qs_ot_get_p(qs_ot_env(1)%matrix_x, qs_ot_env(1)%matrix_sx, qs_ot_env(1))
277 IF (delta < eps_gradient .OR. ieigensolver >= max_iter_inner_loop)
EXIT eigensolver_loop
279 IF (iter_total >= iter_max .AND. qs_ot_env(1)%OT_METHOD_FULL /=
"OT LS")
EXIT eigensolver_loop
281 END DO eigensolver_loop
284 DEALLOCATE (qs_ot_env)
285 CALL dbcsr_release_p(matrix_hc(1)%matrix)
286 DEALLOCATE (matrix_hc)
287 CALL dbcsr_release_p(matrix_orthogonal_space)
289 IF (delta < eps_gradient)
THEN
290 IF ((output_unit > 0) .AND. .NOT. my_silent)
THEN
291 WRITE (unit=output_unit, fmt=
"(T2,A,I0,A)") &
292 "OT| Eigensolver reached convergence in ", iter_total,
" iterations"
296 IF (iter_total >= iter_max)
THEN
297 IF (output_unit > 0)
THEN
299 WRITE (output_unit,
"(A,T60,E20.10)")
" WARNING OT eigensolver did not converge: current gradient", delta
301 WRITE (output_unit, *)
"WARNING : did not converge in ot_eigensolver"
302 WRITE (output_unit, *)
"number of iterations ", iter_total,
" exceeded maximum"
303 WRITE (output_unit, *)
"current gradient / target gradient", delta,
" / ", eps_gradient
312 CALL dbcsr_release_p(matrix_c)
314 CALL timestop(handle)
Interface to (sca)lapack for the Cholesky based procedures.
subroutine, public cp_dbcsr_cholesky_decompose(matrix, n, para_env, blacs_env)
used to replace a symmetric positive def. matrix M with its cholesky decomposition U: M = U^T * U,...
subroutine, public cp_dbcsr_cholesky_invert(matrix, n, para_env, blacs_env, upper_to_full)
used to replace the cholesky decomposition by the inverse
DBCSR operations in CP2K.
subroutine, public cp_dbcsr_m_by_n_from_template(matrix, template, m, n, sym, data_type)
Utility function to create an arbitrary shaped dbcsr matrix with the same processor grid as the templ...
subroutine, public copy_dbcsr_to_fm(matrix, fm)
Copy a DBCSR matrix to a BLACS matrix.
subroutine, public cp_fm_to_dbcsr_row_template(matrix, fm_in, template)
Utility function to copy a specially shaped fm to dbcsr_matrix The result matrix will be the matrix i...
subroutine, public dbcsr_copy_columns_hack(matrix_b, matrix_a, ncol, source_start, target_start, para_env, blacs_env)
hack for dbcsr_copy_columns
represent a full matrix distributed on many processors
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
Defines the basic variable types.
integer, parameter, public dp
logical function, public preconditioner_in_use(preconditioner)
...
computes preconditioners, and implements methods to apply them currently used in qs_ot
collects routines that perform operations directly related to MOs
an eigen-space solver for the generalised symmetric eigenvalue problem for sparse matrices,...
subroutine, public ot_eigensolver(matrix_h, matrix_s, matrix_orthogonal_space_fm, matrix_c_fm, preconditioner, eps_gradient, iter_max, size_ortho_space, silent, ot_settings)
...
subroutine, public ot_mini(qs_ot_env, matrix_hc)
...
subroutine, public qs_ot_init(qs_ot_env)
...
subroutine, public qs_ot_allocate(qs_ot_env, matrix_s, fm_struct_ref, ortho_k)
...
subroutine, public qs_ot_settings_init(settings)
sets default values for the settings type
subroutine, public qs_ot_destroy(qs_ot_env)
...
subroutine, public qs_ot_get_p(matrix_x, matrix_sx, qs_ot_env)
...
subroutine, public qs_ot_get_orbitals(matrix_c, matrix_x, qs_ot_env)
...
subroutine, public qs_ot_new_preconditioner(qs_ot_env, preconditioner)
...