93#include "./base/base_uses.f90"
99 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'preconditioner'
100 REAL(KIND=
dp),
PARAMETER,
PRIVATE :: fermi_low_rank_gap_factor = 4.0_dp, &
101 fermi_low_rank_degeneracy_tolerance = 1.0e-8_dp, &
102 fermi_low_rank_min_window = 1.0_dp
135 SUBROUTINE prepare_lattice_operator(preconditioner_env, operator_matrix, operator_name, rhs_count)
137 TYPE(preconditioner_type) :: preconditioner_env
138 TYPE(dbcsr_type),
POINTER :: operator_matrix
139 CHARACTER(LEN=*),
INTENT(IN) :: operator_name
140 INTEGER,
INTENT(IN) :: rhs_count
142 INTEGER :: alpha, beta, block_size, col_cell, delta_index, i, info, j, local_info, n, ncell, &
143 ncol_local, nrow_local, output_unit, row_cell
144 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: index_to_cell
145 INTEGER,
DIMENSION(3) :: delta
146 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
148 REAL(KIND=
dp) :: denominator, difference, numerator,
value
149 REAL(KIND=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: dense_operator, xkp
150 REAL(KIND=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: blocks
151 REAL(KIND=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
152 POINTER :: local_data
153 TYPE(cp_fm_struct_type),
POINTER :: fm_struct
154 TYPE(cp_fm_type) :: operator_fm, work
155 TYPE(cp_logger_type),
POINTER :: logger
157 cpassert(
ASSOCIATED(operator_matrix))
159 preconditioner_env%lattice_fft_active = .false.
160 preconditioner_env%lattice_projection_error = 0.0_dp
161 preconditioner_env%lattice_corrected_projection_error = 0.0_dp
162 preconditioner_env%lattice_cost_ratio = 0.0_dp
163 preconditioner_env%lattice_storage_ratio = 0.0_dp
165 IF (any(preconditioner_env%lattice_dims <= 0)) cpabort(
"Lattice dimensions must be positive")
169 IF (preconditioner_env%para_env%is_source())
THEN
172 IF (output_unit > 0)
THEN
173 WRITE (output_unit,
'(T2,A,A,A,I0,A,I0)') &
174 "OT| Lattice FFT AUTO kept the conventional ", trim(operator_name), &
175 " solver: ", product(preconditioner_env%lattice_dims), &
184 ncell = product(preconditioner_env%lattice_dims)
185 IF (
modulo(n, ncell) /= 0) cpabort(
"AO dimension does not match replicated cells")
187 preconditioner_env%lattice_block_size = block_size
189 preconditioner_env%lattice_dims, block_size, rhs_count, &
190 preconditioner_env%para_env%num_pe) + &
192 preconditioner_env%lattice_dims, &
193 preconditioner_env%lattice_local_cells)
195 preconditioner_env%lattice_dims, 1) + &
197 preconditioner_env%lattice_dims, 1, &
198 preconditioner_env%lattice_local_cells)
202 IF (preconditioner_env%para_env%is_source())
THEN
205 IF (output_unit > 0)
THEN
206 WRITE (output_unit,
'(T2,A,A,A,F8.3,A,F8.3,A)') &
207 "OT| Lattice FFT AUTO kept the conventional ", trim(operator_name), &
208 " solver: estimated work ratio ", preconditioner_env%lattice_cost_ratio, &
209 " storage ratio ", preconditioner_env%lattice_storage_ratio,
" selected: F"
215 context=preconditioner_env%ctxt, &
216 para_env=preconditioner_env%para_env)
217 CALL cp_fm_create(operator_fm, fm_struct, name=
"lattice preconditioner operator")
221 CALL cp_fm_create(work, operator_fm%matrix_struct, name=
"lattice operator work")
224 CALL cp_fm_get_info(operator_fm, nrow_local=nrow_local, ncol_local=ncol_local, &
225 row_indices=row_indices, col_indices=col_indices, local_data=local_data)
226 ALLOCATE (blocks(block_size, block_size, ncell), source=0.0_dp)
227 ALLOCATE (index_to_cell(3, ncell), xkp(3, ncell))
228 CALL lattice_grid(preconditioner_env%lattice_dims, index_to_cell, xkp)
229 IF (preconditioner_env%lattice_local_cells > 0)
THEN
230 ALLOCATE (dense_operator(n, n), source=0.0_dp)
235 IF (row_indices(i) <= col_indices(j))
THEN
236 value = local_data(i, j)
237 row_cell = (row_indices(i) - 1)/block_size + 1
238 col_cell = (col_indices(j) - 1)/block_size + 1
239 alpha =
modulo(row_indices(i) - 1, block_size) + 1
240 beta =
modulo(col_indices(j) - 1, block_size) + 1
241 delta =
modulo(index_to_cell(:, row_cell) - index_to_cell(:, col_cell), &
242 preconditioner_env%lattice_dims)
243 delta_index = delta(1) + preconditioner_env%lattice_dims(1)*(delta(2) + &
244 preconditioner_env%lattice_dims(2)*delta(3)) + 1
245 blocks(alpha, beta, delta_index) = blocks(alpha, beta, delta_index) + &
246 value/real(ncell, kind=
dp)
247 denominator = denominator +
value*
value
248 IF (
ALLOCATED(dense_operator))
THEN
249 dense_operator(row_indices(i), col_indices(j)) =
value
251 IF (row_indices(i) < col_indices(j))
THEN
252 delta =
modulo(index_to_cell(:, col_cell) - index_to_cell(:, row_cell), &
253 preconditioner_env%lattice_dims)
254 delta_index = delta(1) + preconditioner_env%lattice_dims(1)*(delta(2) + &
255 preconditioner_env%lattice_dims(2)*delta(3)) + 1
256 blocks(beta, alpha, delta_index) = blocks(beta, alpha, delta_index) + &
257 value/real(ncell, kind=
dp)
258 denominator = denominator +
value*
value
263 CALL preconditioner_env%para_env%sum(blocks)
267 IF (row_indices(i) <= col_indices(j))
THEN
268 value = local_data(i, j)
269 row_cell = (row_indices(i) - 1)/block_size + 1
270 col_cell = (col_indices(j) - 1)/block_size + 1
271 alpha =
modulo(row_indices(i) - 1, block_size) + 1
272 beta =
modulo(col_indices(j) - 1, block_size) + 1
273 delta =
modulo(index_to_cell(:, row_cell) - index_to_cell(:, col_cell), &
274 preconditioner_env%lattice_dims)
275 delta_index = delta(1) + preconditioner_env%lattice_dims(1)*(delta(2) + &
276 preconditioner_env%lattice_dims(2)*delta(3)) + 1
277 difference =
value - blocks(alpha, beta, delta_index)
278 numerator = numerator + difference*difference
279 IF (row_indices(i) < col_indices(j))
THEN
280 delta =
modulo(index_to_cell(:, col_cell) - index_to_cell(:, row_cell), &
281 preconditioner_env%lattice_dims)
282 delta_index = delta(1) + preconditioner_env%lattice_dims(1)*(delta(2) + &
283 preconditioner_env%lattice_dims(2)*delta(3)) + 1
284 difference =
value - blocks(beta, alpha, delta_index)
285 numerator = numerator + difference*difference
290 CALL preconditioner_env%para_env%sum(numerator)
291 CALL preconditioner_env%para_env%sum(denominator)
292 preconditioner_env%lattice_projection_error = &
293 sqrt(numerator/max(denominator, tiny(denominator)))
295 blocks, preconditioner_env%lattice_dims, preconditioner_env%lattice_inverse_k, used_fft, info)
296 preconditioner_env%lattice_corrected_projection_error = &
297 preconditioner_env%lattice_projection_error
298 IF (
ALLOCATED(dense_operator))
THEN
299 CALL preconditioner_env%para_env%sum(dense_operator)
302 dense_operator(i, j) = dense_operator(j, i)
306 dense_operator, preconditioner_env%lattice_dims, &
307 preconditioner_env%lattice_local_cells, &
308 preconditioner_env%lattice_local_indices, &
309 preconditioner_env%lattice_local_operator, &
310 preconditioner_env%lattice_local_coarse_inverse, &
311 preconditioner_env%lattice_corrected_projection_error, local_info)
312 IF (local_info /= 0)
THEN
313 cpabort(
"LATTICE_FFT local correction found a non-positive coarse operator")
315 DEALLOCATE (dense_operator)
318 DEALLOCATE (blocks, index_to_cell, xkp)
319 SELECT CASE (preconditioner_env%lattice_fft_mode)
322 cpabort(
"LATTICE_FFT found a non-positive Fourier block for "//trim(operator_name))
324 IF (.NOT. used_fft)
THEN
325 cpabort(
"LATTICE_FFT could not initialize its FFT for "//trim(operator_name))
327 preconditioner_env%lattice_fft_active = .true.
330 preconditioner_env%lattice_dims, &
331 preconditioner_env%lattice_block_size, rhs_count, 1, &
332 preconditioner_env%para_env%num_pe, &
333 preconditioner_env%lattice_projection_error, used_fft, info)
335 cpabort(
"Unknown LATTICE_FFT mode")
338 IF (.NOT. preconditioner_env%lattice_fft_active .AND. &
339 ALLOCATED(preconditioner_env%lattice_inverse_k))
THEN
340 DEALLOCATE (preconditioner_env%lattice_inverse_k)
342 IF (preconditioner_env%para_env%is_source())
THEN
345 IF (output_unit > 0)
THEN
346 WRITE (output_unit,
'(T2,A,A,A,3(I0,1X),A,I0)') &
347 "OT| Lattice FFT ", trim(operator_name),
" cells: ", &
348 preconditioner_env%lattice_dims,
"AO block: ", preconditioner_env%lattice_block_size
349 WRITE (output_unit,
'(T2,A,ES12.4,A,L1)') &
350 "OT| Block-circulant projection error: ", &
351 preconditioner_env%lattice_projection_error, &
352 " selected: ", preconditioner_env%lattice_fft_active
353 IF (preconditioner_env%lattice_local_cells > 0)
THEN
354 WRITE (output_unit,
'(T2,A,I0,A,ES12.4)') &
355 "OT| Balanced local correction cells: ", &
356 preconditioner_env%lattice_local_cells,
" residual error: ", &
357 preconditioner_env%lattice_corrected_projection_error
359 WRITE (output_unit,
'(T2,A,F8.3,A,F8.3)') &
360 "OT| Estimated lattice/dense work ratio: ", &
361 preconditioner_env%lattice_cost_ratio,
" storage ratio: ", &
362 preconditioner_env%lattice_storage_ratio
366 END SUBROUTINE prepare_lattice_operator
374 SUBROUTINE prepare_lattice_state_operator(preconditioner_env, matrix_s, operator_name)
376 TYPE(preconditioner_type) :: preconditioner_env
377 TYPE(dbcsr_type),
POINTER :: matrix_s
378 CHARACTER(LEN=*),
INTENT(IN) :: operator_name
380 COMPLEX(KIND=dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: inverse_k
381 INTEGER :: i, info, istate, j, local_info, &
382 local_rank, n, ncell, ncol_local, &
383 nrow_local, nstate, output_unit
384 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: local_indices
385 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
386 LOGICAL :: all_selected, selected, used_fft
387 REAL(KIND=
dp) :: corrected_projection_error, &
389 REAL(KIND=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: dense_operator, dense_sv, dense_vectors, &
390 local_coarse_inverse, local_operator, &
392 REAL(KIND=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
393 POINTER :: local_data
394 TYPE(cp_fm_type) :: sv_fm
395 TYPE(cp_logger_type),
POINTER :: logger
397 cpassert(
ASSOCIATED(matrix_s))
398 cpassert(
ASSOCIATED(preconditioner_env%fm))
399 cpassert(
ASSOCIATED(preconditioner_env%full_evals))
400 cpassert(
ASSOCIATED(preconditioner_env%occ_evals))
403 preconditioner_env%lattice_fft_active = .false.
404 preconditioner_env%lattice_projection_error = 0.0_dp
405 preconditioner_env%lattice_corrected_projection_error = 0.0_dp
406 preconditioner_env%lattice_cost_ratio = 0.0_dp
407 preconditioner_env%lattice_storage_ratio = 0.0_dp
408 IF (
ALLOCATED(preconditioner_env%lattice_state_inverse_k))
THEN
409 DEALLOCATE (preconditioner_env%lattice_state_inverse_k)
411 IF (
ALLOCATED(preconditioner_env%lattice_occ_vectors))
THEN
412 DEALLOCATE (preconditioner_env%lattice_occ_vectors)
414 IF (
ALLOCATED(preconditioner_env%lattice_occ_dual))
THEN
415 DEALLOCATE (preconditioner_env%lattice_occ_dual)
417 IF (
ALLOCATED(preconditioner_env%lattice_local_indices))
THEN
418 DEALLOCATE (preconditioner_env%lattice_local_indices)
420 IF (
ALLOCATED(preconditioner_env%lattice_local_operator))
THEN
421 DEALLOCATE (preconditioner_env%lattice_local_operator)
423 IF (
ALLOCATED(preconditioner_env%lattice_local_coarse_inverse))
THEN
424 DEALLOCATE (preconditioner_env%lattice_local_coarse_inverse)
426 IF (
ALLOCATED(preconditioner_env%lattice_state_local_indices))
THEN
427 DEALLOCATE (preconditioner_env%lattice_state_local_indices)
429 IF (
ALLOCATED(preconditioner_env%lattice_state_local_operator))
THEN
430 DEALLOCATE (preconditioner_env%lattice_state_local_operator)
432 IF (
ALLOCATED(preconditioner_env%lattice_state_local_coarse_inverse))
THEN
433 DEALLOCATE (preconditioner_env%lattice_state_local_coarse_inverse)
435 IF (any(preconditioner_env%lattice_dims <= 0)) cpabort(
"Lattice dimensions must be positive")
438 IF (preconditioner_env%para_env%is_source())
THEN
441 IF (output_unit > 0)
THEN
442 WRITE (output_unit,
'(T2,A,A,A,I0,A,I0)') &
443 "OT| Lattice FFT AUTO kept the conventional ", trim(operator_name), &
444 " solver: ", product(preconditioner_env%lattice_dims), &
451 CALL cp_fm_get_info(preconditioner_env%fm, nrow_global=n, ncol_global=j)
452 cpassert(j == n .AND.
SIZE(preconditioner_env%full_evals) == n)
453 nstate =
SIZE(preconditioner_env%occ_evals)
455 ncell = product(preconditioner_env%lattice_dims)
456 IF (
modulo(n, ncell) /= 0) cpabort(
"AO dimension does not match replicated cells")
457 preconditioner_env%lattice_block_size = n/ncell
459 preconditioner_env%lattice_dims, &
460 preconditioner_env%lattice_block_size, nstate, &
461 preconditioner_env%para_env%num_pe)
463 preconditioner_env%lattice_dims, nstate)
464 preconditioner_env%lattice_cost_ratio = preconditioner_env%lattice_cost_ratio + &
466 preconditioner_env%lattice_dims, &
467 preconditioner_env%lattice_local_cells)
468 preconditioner_env%lattice_storage_ratio = preconditioner_env%lattice_storage_ratio + &
470 preconditioner_env%lattice_dims, nstate, &
471 preconditioner_env%lattice_local_cells)
475 IF (preconditioner_env%para_env%is_source())
THEN
478 IF (output_unit > 0)
THEN
479 WRITE (output_unit,
'(T2,A,A,A,F8.3,A,F8.3,A)') &
480 "OT| Lattice FFT AUTO kept the conventional ", trim(operator_name), &
481 " solver: estimated work ratio ", preconditioner_env%lattice_cost_ratio, &
482 " storage ratio ", preconditioner_env%lattice_storage_ratio,
" selected: F"
487 IF (preconditioner_env%lattice_local_cells > 0)
THEN
488 local_rank = preconditioner_env%lattice_local_cells* &
489 preconditioner_env%lattice_block_size
490 ALLOCATE (preconditioner_env%lattice_state_local_indices(local_rank, nstate), &
491 preconditioner_env%lattice_state_local_operator(n, local_rank, nstate), &
492 preconditioner_env%lattice_state_local_coarse_inverse(local_rank, local_rank, nstate))
494 CALL cp_fm_create(sv_fm, preconditioner_env%fm%matrix_struct, name=
"lattice FULL_ALL S V")
496 CALL cp_fm_get_info(sv_fm, nrow_local=nrow_local, ncol_local=ncol_local, &
497 row_indices=row_indices, col_indices=col_indices, local_data=local_data)
498 ALLOCATE (dense_sv(n, n), dense_vectors(n, nstate), source=0.0_dp)
501 dense_sv(row_indices(i), col_indices(j)) = local_data(i, j)
504 CALL preconditioner_env%para_env%sum(dense_sv)
507 CALL cp_fm_get_info(preconditioner_env%fm, nrow_local=nrow_local, ncol_local=ncol_local, &
508 row_indices=row_indices, col_indices=col_indices, local_data=local_data)
510 IF (col_indices(j) > nstate) cycle
512 dense_vectors(row_indices(i), col_indices(j)) = local_data(i, j)
515 CALL preconditioner_env%para_env%sum(dense_vectors)
516 ALLOCATE (preconditioner_env%lattice_occ_vectors(n, nstate), &
517 preconditioner_env%lattice_occ_dual(n, nstate))
518 preconditioner_env%lattice_occ_vectors(:, :) = dense_vectors
519 preconditioner_env%lattice_occ_dual(:, :) = dense_sv(:, 1:nstate)
521 ALLOCATE (dense_operator(n, n), scaled_sv(n, n))
522 all_selected = .true.
523 DO istate = 1, nstate
524 scaled_sv(:, :) = dense_sv
526 scaled_sv(:, j) = scaled_sv(:, j)*max( &
527 preconditioner_env%energy_gap, &
528 preconditioner_env%full_evals(j) - preconditioner_env%occ_evals(istate))
530 dense_operator(:, :) = matmul(scaled_sv, transpose(dense_sv))
532 projection_error, used_fft, info)
533 preconditioner_env%lattice_projection_error = &
534 max(preconditioner_env%lattice_projection_error, projection_error)
535 corrected_projection_error = projection_error
536 IF (preconditioner_env%lattice_local_cells > 0)
THEN
538 dense_operator, preconditioner_env%lattice_dims, &
539 preconditioner_env%lattice_local_cells, local_indices, &
540 local_operator, local_coarse_inverse, corrected_projection_error, local_info)
541 IF (local_info /= 0)
THEN
542 cpabort(
"LATTICE_FFT local correction found a non-positive coarse operator")
544 preconditioner_env%lattice_state_local_indices(:, istate) = local_indices
545 preconditioner_env%lattice_state_local_operator(:, :, istate) = local_operator
546 preconditioner_env%lattice_state_local_coarse_inverse(:, :, istate) = local_coarse_inverse
547 DEALLOCATE (local_coarse_inverse, local_indices, local_operator)
549 preconditioner_env%lattice_corrected_projection_error = &
550 max(preconditioner_env%lattice_corrected_projection_error, corrected_projection_error)
552 preconditioner_env%lattice_block_size, nstate, nstate, &
553 preconditioner_env%para_env%num_pe, projection_error, used_fft, info)
556 cpabort(
"LATTICE_FFT found a non-positive Fourier block for "//trim(operator_name))
558 IF (.NOT. used_fft)
THEN
559 cpabort(
"LATTICE_FFT could not initialize its FFT for "//trim(operator_name))
562 all_selected = all_selected .AND. selected
564 IF (.NOT.
ALLOCATED(preconditioner_env%lattice_state_inverse_k))
THEN
565 ALLOCATE (preconditioner_env%lattice_state_inverse_k( &
566 SIZE(inverse_k, 1),
SIZE(inverse_k, 2),
SIZE(inverse_k, 3), nstate))
568 IF (info == 0 .AND. used_fft)
THEN
569 preconditioner_env%lattice_state_inverse_k(:, :, :, istate) = inverse_k
571 DEALLOCATE (inverse_k)
574 preconditioner_env%lattice_fft_active = &
576 IF (.NOT. preconditioner_env%lattice_fft_active .AND. &
577 ALLOCATED(preconditioner_env%lattice_state_inverse_k))
THEN
578 DEALLOCATE (preconditioner_env%lattice_state_inverse_k)
580 IF (.NOT. preconditioner_env%lattice_fft_active)
THEN
581 DEALLOCATE (preconditioner_env%lattice_occ_vectors, &
582 preconditioner_env%lattice_occ_dual)
583 IF (
ALLOCATED(preconditioner_env%lattice_state_local_indices))
THEN
584 DEALLOCATE (preconditioner_env%lattice_state_local_indices, &
585 preconditioner_env%lattice_state_local_operator, &
586 preconditioner_env%lattice_state_local_coarse_inverse)
589 IF (preconditioner_env%para_env%is_source())
THEN
592 IF (output_unit > 0)
THEN
593 WRITE (output_unit,
'(T2,A,A,A,3(I0,1X),A,I0,A,I0)') &
594 "OT| Lattice FFT ", trim(operator_name),
" cells: ", &
595 preconditioner_env%lattice_dims,
"AO block: ", &
596 preconditioner_env%lattice_block_size,
" states: ", nstate
597 WRITE (output_unit,
'(T2,A,ES12.4,A,L1)') &
598 "OT| Maximum block-circulant projection error: ", &
599 preconditioner_env%lattice_projection_error, &
600 " selected: ", preconditioner_env%lattice_fft_active
601 IF (preconditioner_env%lattice_local_cells > 0)
THEN
602 WRITE (output_unit,
'(T2,A,I0,A,ES12.4)') &
603 "OT| Balanced local correction cells/state: ", &
604 preconditioner_env%lattice_local_cells,
" maximum residual error: ", &
605 preconditioner_env%lattice_corrected_projection_error
607 WRITE (output_unit,
'(T2,A,F8.3,A,F8.3)') &
608 "OT| Estimated lattice/dense work ratio: ", &
609 preconditioner_env%lattice_cost_ratio,
" storage ratio: ", &
610 preconditioner_env%lattice_storage_ratio
614 DEALLOCATE (dense_operator, dense_sv, dense_vectors, scaled_sv)
616 END SUBROUTINE prepare_lattice_state_operator
623 SUBROUTINE prepare_low_rank_base(preconditioner_env, matrix_s)
625 TYPE(preconditioner_type) :: preconditioner_env
626 TYPE(dbcsr_type),
OPTIONAL,
POINTER :: matrix_s
629 TYPE(cp_fm_type) :: work
631 cpassert(
ASSOCIATED(preconditioner_env%fm))
632 cpassert(.NOT.
ASSOCIATED(preconditioner_env%base_fm))
635 IF (.NOT.
PRESENT(matrix_s))
THEN
636 cpabort(
"LATTICE_FFT requires a non-unit overlap metric for FERMI_LOW_RANK")
638 cpassert(
ASSOCIATED(matrix_s))
639 CALL prepare_lattice_operator(preconditioner_env, matrix_s,
"FERMI_LOW_RANK overlap", &
640 SIZE(preconditioner_env%occ_evals))
641 IF (preconditioner_env%lattice_fft_active)
THEN
649 cpabort(
"Unknown FERMI_LOW_RANK base operator")
651 ALLOCATE (preconditioner_env%base_fm)
652 CALL cp_fm_create(preconditioner_env%base_fm, preconditioner_env%fm%matrix_struct, &
653 name=
"FERMI_LOW_RANK overlap inverse")
655 IF (
PRESENT(matrix_s))
THEN
656 cpassert(
ASSOCIATED(matrix_s))
659 IF (info /= 0) cpabort(
"FERMI_LOW_RANK requires a positive-definite overlap matrix")
661 CALL cp_fm_create(work, preconditioner_env%base_fm%matrix_struct, name=
"low-rank base work")
665 CALL cp_fm_set_all(preconditioner_env%base_fm, alpha=0.0_dp, beta=1.0_dp)
668 END SUBROUTINE prepare_low_rank_base
696 matrix_t, mo_set, energy_gap, convert_precond_to_dbcsr, chol_type)
699 INTEGER,
INTENT(IN) :: precon_type, solver_type
701 TYPE(
dbcsr_type),
OPTIONAL,
POINTER :: matrix_s, matrix_t
703 REAL(kind=
dp) :: energy_gap
704 LOGICAL,
INTENT(IN),
OPTIONAL :: convert_precond_to_dbcsr
705 INTEGER,
INTENT(IN),
OPTIONAL :: chol_type
707 CHARACTER(len=*),
PARAMETER :: routinen =
'make_preconditioner'
709 INTEGER :: handle, k, max_rank, my_solver_type, &
710 nao, nhomo, output_unit
711 LOGICAL :: my_convert_precond_to_dbcsr, &
712 needs_full_spectrum, needs_homo, &
714 REAL(kind=
dp) :: energy_homo
715 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenvalues_ot
722 CALL timeset(routinen, handle)
724 CALL get_mo_set(mo_set=mo_set, mo_coeff=mo_coeff, mo_coeff_b=mo_coeff_b, homo=nhomo)
725 use_mo_coeff_b = mo_set%use_mo_coeff_b
729 my_convert_precond_to_dbcsr = .false.
730 IF (
PRESENT(convert_precond_to_dbcsr)) my_convert_precond_to_dbcsr = convert_precond_to_dbcsr
735 my_convert_precond_to_dbcsr = .false.
745 needs_full_spectrum = .false.
748 SELECT CASE (precon_type)
750 needs_full_spectrum = .true.
752 IF (use_mo_coeff_b)
THEN
758 needs_full_spectrum = .true.
763 cpabort(
"The preconditioner is unknown ...")
766 ALLOCATE (eigenvalues_ot(k))
768 IF (needs_full_spectrum)
THEN
775 IF (use_mo_coeff_b)
THEN
777 eigenvalues_ot, do_rotation=.false., &
778 para_env=mo_coeff%matrix_struct%para_env, &
779 blacs_env=mo_coeff%matrix_struct%context)
782 eigenvalues_ot, do_rotation=.false.)
785 cpassert(nhomo > 0 .AND. nhomo <= k)
786 energy_homo = eigenvalues_ot(nhomo)
790 cpabort(
"Not yet implemented")
797 my_solver_type = solver_type
798 preconditioner_env%in_use = precon_type
800 IF (
PRESENT(chol_type)) preconditioner_env%cholesky_use = chol_type
801 preconditioner_env%in_use = precon_type
802 preconditioner_env%lattice_fft_active = .false.
803 preconditioner_env%lattice_corrected_projection_error = 0.0_dp
804 IF (
ALLOCATED(preconditioner_env%lattice_inverse_k))
THEN
805 DEALLOCATE (preconditioner_env%lattice_inverse_k)
807 IF (
ALLOCATED(preconditioner_env%lattice_state_inverse_k))
THEN
808 DEALLOCATE (preconditioner_env%lattice_state_inverse_k)
810 IF (
ALLOCATED(preconditioner_env%lattice_occ_vectors))
THEN
811 DEALLOCATE (preconditioner_env%lattice_occ_vectors)
813 IF (
ALLOCATED(preconditioner_env%lattice_occ_dual))
THEN
814 DEALLOCATE (preconditioner_env%lattice_occ_dual)
816 IF (
ALLOCATED(preconditioner_env%lattice_local_indices))
THEN
817 DEALLOCATE (preconditioner_env%lattice_local_indices)
819 IF (
ALLOCATED(preconditioner_env%lattice_local_operator))
THEN
820 DEALLOCATE (preconditioner_env%lattice_local_operator)
822 IF (
ALLOCATED(preconditioner_env%lattice_local_coarse_inverse))
THEN
823 DEALLOCATE (preconditioner_env%lattice_local_coarse_inverse)
825 IF (
ALLOCATED(preconditioner_env%lattice_state_local_indices))
THEN
826 DEALLOCATE (preconditioner_env%lattice_state_local_indices)
828 IF (
ALLOCATED(preconditioner_env%lattice_state_local_operator))
THEN
829 DEALLOCATE (preconditioner_env%lattice_state_local_operator)
831 IF (
ALLOCATED(preconditioner_env%lattice_state_local_coarse_inverse))
THEN
832 DEALLOCATE (preconditioner_env%lattice_state_local_coarse_inverse)
836 energy_homo, eigenvalues_ot, energy_gap, my_solver_type)
839 context=preconditioner_env%ctxt, &
840 para_env=preconditioner_env%para_env)
846 energy_homo, eigenvalues_ot(1:nhomo), energy_gap, my_solver_type)
852 SELECT CASE (precon_type)
854 cpassert(
ASSOCIATED(preconditioner_env%sparse_matrix))
855 CALL prepare_lattice_operator(preconditioner_env, preconditioner_env%sparse_matrix, &
856 "FULL_KINETIC", nhomo)
858 cpassert(
ASSOCIATED(preconditioner_env%sparse_matrix))
859 CALL prepare_lattice_operator(preconditioner_env, preconditioner_env%sparse_matrix, &
860 "FULL_SINGLE_INVERSE", nhomo)
862 cpassert(
ASSOCIATED(preconditioner_env%sparse_matrix))
863 CALL prepare_lattice_operator(preconditioner_env, preconditioner_env%sparse_matrix, &
864 "FULL_S_INVERSE", nhomo)
866 cpassert(
PRESENT(matrix_s))
867 cpassert(
ASSOCIATED(matrix_s))
868 CALL prepare_lattice_state_operator(preconditioner_env, matrix_s, &
869 "FULL_ALL_COVARIANT")
873 IF (.NOT. preconditioner_env%lattice_fft_active)
THEN
880 preconditioner_env%spectral_reference = energy_homo
881 preconditioner_env%spectral_window = &
882 max(fermi_low_rank_min_window, fermi_low_rank_gap_factor*preconditioner_env%energy_gap)
883 preconditioner_env%spectral_base_scale = 1.0_dp/preconditioner_env%spectral_window
884 max_rank = preconditioner_env%spectral_max_rank
885 IF (max_rank == -1) max_rank =
SIZE(preconditioner_env%full_evals) - nhomo
887 preconditioner_env%full_evals, nhomo, max_rank, &
888 fermi_low_rank_degeneracy_tolerance)
889 CALL prepare_low_rank_base(preconditioner_env, matrix_s)
890 IF (preconditioner_env%lattice_fft_active)
THEN
893 DO WHILE (preconditioner_env%spectral_rank > 0)
895 preconditioner_env%full_evals(nhomo + preconditioner_env%spectral_rank), &
896 preconditioner_env%spectral_reference, preconditioner_env%energy_gap) >= &
897 preconditioner_env%spectral_base_scale)
EXIT
898 preconditioner_env%spectral_rank = preconditioner_env%spectral_rank - 1
901 IF (preconditioner_env%para_env%is_source())
THEN
904 IF (output_unit > 0)
THEN
905 WRITE (output_unit,
'(T2,A,F14.8,A,I0)') &
906 "OT| FERMI_LOW_RANK common reference [hartree]: ", &
907 preconditioner_env%spectral_reference,
" retained rank: ", &
908 preconditioner_env%spectral_rank
916 IF (.NOT. preconditioner_env%lattice_fft_active)
THEN
917 IF (my_convert_precond_to_dbcsr)
THEN
922 preconditioner_env%base_dbcsr_matrix, matrix_h)
926 preconditioner_env%para_env, preconditioner_env%ctxt)
930 DEALLOCATE (eigenvalues_ot)
932 CALL timestop(handle)
950 matrix_c_re, matrix_c_im, &
951 matrix_h_re, matrix_h_im, &
952 matrix_s_re, matrix_s_im, &
953 mo_set, energy_gap, solver_type)
956 TYPE(
dbcsr_type),
POINTER :: matrix_c_re, matrix_c_im, matrix_h_re, &
957 matrix_h_im, matrix_s_re, matrix_s_im
959 REAL(kind=
dp),
INTENT(IN) :: energy_gap
960 INTEGER,
INTENT(IN) :: solver_type
962 CHARACTER(len=*),
PARAMETER :: routinen =
'make_preconditioner_complex_full_all'
965 REAL(kind=
dp),
DIMENSION(:),
POINTER :: eigenvalues
968 CALL timeset(routinen, handle)
970 NULLIFY (eigenvalues)
971 cpassert(
ASSOCIATED(matrix_c_re))
972 cpassert(
ASSOCIATED(matrix_c_im))
973 cpassert(
ASSOCIATED(matrix_h_re))
974 cpassert(
ASSOCIATED(matrix_h_im))
975 cpassert(
ASSOCIATED(matrix_s_re))
976 cpassert(
ASSOCIATED(matrix_s_im))
978 cpabort(
'Complex FULL_ALL supports only PRECOND_SOLVER DEFAULT')
982 CALL get_mo_set(mo_set, eigenvalues=eigenvalues)
983 cpassert(
ASSOCIATED(eigenvalues))
984 cpassert(
SIZE(eigenvalues) >= k)
987 'complex FULL_ALL C', matrix_c)
989 'complex FULL_ALL H', matrix_h)
991 'complex FULL_ALL S', matrix_s)
993 eigenvalues(1:k), energy_gap)
999 CALL timestop(handle)
1015 matrix_h_re, matrix_h_im, &
1016 matrix_s_re, matrix_s_im, &
1017 mo_set, energy_gap, solver_type)
1020 TYPE(
dbcsr_type),
POINTER :: matrix_h_re, matrix_h_im, matrix_s_re, &
1023 REAL(kind=
dp),
INTENT(IN) :: energy_gap
1024 INTEGER,
INTENT(IN) :: solver_type
1027 REAL(kind=
dp),
DIMENSION(:),
POINTER :: eigenvalues
1030 NULLIFY (eigenvalues)
1031 cpassert(
ASSOCIATED(matrix_h_re))
1032 cpassert(
ASSOCIATED(matrix_h_im))
1033 cpassert(
ASSOCIATED(matrix_s_re))
1034 cpassert(
ASSOCIATED(matrix_s_im))
1036 cpabort(
'Complex FULL_SINGLE supports only PRECOND_SOLVER DEFAULT')
1038 CALL get_mo_set(mo_set, homo=homo, eigenvalues=eigenvalues)
1039 cpassert(
ASSOCIATED(eigenvalues))
1040 cpassert(homo > 0 .AND. homo <=
SIZE(eigenvalues))
1043 'complex FULL_SINGLE H', matrix_h)
1045 'complex FULL_SINGLE S', matrix_s)
1047 eigenvalues(homo), energy_gap)
1067 preconditioner_env, matrix_c_re, matrix_c_im, matrix_h_re, matrix_h_im, &
1068 matrix_s_re, matrix_s_im, energy_gap, max_rank, solver_type)
1071 TYPE(
dbcsr_type),
POINTER :: matrix_c_re, matrix_c_im, matrix_h_re, &
1072 matrix_h_im, matrix_s_re, matrix_s_im
1073 REAL(kind=
dp),
INTENT(IN) :: energy_gap
1074 INTEGER,
INTENT(IN) :: max_rank, solver_type
1079 cpabort(
'Complex FERMI_LOW_RANK supports only PRECOND_SOLVER DEFAULT')
1083 'complex FERMI_LOW_RANK C', matrix_c)
1085 'complex FERMI_LOW_RANK H', matrix_h)
1087 'complex FERMI_LOW_RANK S', matrix_s)
1089 preconditioner_env, matrix_c, matrix_h, matrix_s, energy_gap, &
1090 max_rank, max(fermi_low_rank_min_window, fermi_low_rank_gap_factor*energy_gap), &
1091 fermi_low_rank_degeneracy_tolerance)
1113 preconditioner_env, matrix_c_re, matrix_c_im, matrix_h_re, matrix_h_im, &
1114 matrix_s_re, matrix_s_im, energy_gap, solver_type, occupation_signature)
1117 TYPE(
dbcsr_type),
POINTER :: matrix_c_re, matrix_c_im, matrix_h_re, &
1118 matrix_h_im, matrix_s_re, matrix_s_im
1119 REAL(kind=
dp),
INTENT(IN) :: energy_gap
1120 INTEGER,
INTENT(IN) :: solver_type
1121 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN), &
1122 OPTIONAL :: occupation_signature
1127 cpabort(
'Complex FULL_ALL_COVARIANT supports only PRECOND_SOLVER DEFAULT')
1130 'complex FULL_ALL_COVARIANT C', matrix_c)
1132 'complex FULL_ALL_COVARIANT H', matrix_h)
1134 'complex FULL_ALL_COVARIANT S', matrix_s)
1136 energy_gap, occupation_signature)
1157 matrix_c_re, matrix_c_im, &
1158 matrix_h_re, matrix_h_im, &
1159 matrix_s_re, matrix_s_im, &
1160 energy_gap, solver_type)
1163 TYPE(
dbcsr_type),
POINTER :: matrix_c_re, matrix_c_im, matrix_h_re, &
1164 matrix_h_im, matrix_s_re, matrix_s_im
1165 REAL(kind=
dp),
INTENT(IN) :: energy_gap
1166 INTEGER,
INTENT(IN) :: solver_type
1171 TYPE(
cp_fm_type) :: matrix_c_im_fm, matrix_c_re_fm, &
1172 matrix_h_im_fm, matrix_h_re_fm, &
1173 matrix_s_im_fm, matrix_s_re_fm
1175 NULLIFY (fm_struct_mo, fm_struct_square)
1176 cpassert(
ASSOCIATED(matrix_c_re))
1177 cpassert(
ASSOCIATED(matrix_c_im))
1178 cpassert(
ASSOCIATED(matrix_h_re))
1179 cpassert(
ASSOCIATED(matrix_h_im))
1180 cpassert(
ASSOCIATED(matrix_s_re))
1181 cpassert(
ASSOCIATED(matrix_s_im))
1184 cpabort(
"Complex FULL_SINGLE_INVERSE supports only PRECOND_SOLVER DEFAULT/INVERSE_CHOLESKY")
1186 CALL dbcsr_get_info(matrix_c_re, nfullrows_total=n, nfullcols_total=k)
1187 cpassert(n > 0 .AND. k > 0 .AND. k <= n)
1190 context=preconditioner_env%ctxt, &
1191 para_env=preconditioner_env%para_env)
1193 context=preconditioner_env%ctxt, &
1194 para_env=preconditioner_env%para_env)
1195 CALL cp_fm_create(matrix_c_re_fm, fm_struct_mo, name=
'complex preconditioner C real')
1196 CALL cp_fm_create(matrix_c_im_fm, fm_struct_mo, name=
'complex preconditioner C imaginary')
1197 CALL cp_fm_create(matrix_h_re_fm, fm_struct_square, name=
'complex preconditioner H real')
1198 CALL cp_fm_create(matrix_h_im_fm, fm_struct_square, name=
'complex preconditioner H imaginary')
1199 CALL cp_fm_create(matrix_s_re_fm, fm_struct_square, name=
'complex preconditioner S real')
1200 CALL cp_fm_create(matrix_s_im_fm, fm_struct_square, name=
'complex preconditioner S imaginary')
1210 CALL cp_cfm_create(matrix_c, matrix_c_re_fm%matrix_struct, name=
'complex preconditioner C')
1211 CALL cp_cfm_create(matrix_h, matrix_h_re_fm%matrix_struct, name=
'complex preconditioner H')
1212 CALL cp_cfm_create(matrix_s, matrix_s_re_fm%matrix_struct, name=
'complex preconditioner S')
1213 CALL cp_fm_to_cfm(matrix_c_re_fm, matrix_c_im_fm, matrix_c)
1214 CALL cp_fm_to_cfm(matrix_h_re_fm, matrix_h_im_fm, matrix_h)
1215 CALL cp_fm_to_cfm(matrix_s_re_fm, matrix_s_im_fm, matrix_s)
1218 preconditioner_env%solver = solver_type
1240 matrix_s_re, matrix_s_im, solver_type)
1243 TYPE(
dbcsr_type),
POINTER :: matrix_s_re, matrix_s_im
1244 INTEGER,
INTENT(IN) :: solver_type
1250 cpabort(
"Complex FULL_S_INVERSE supports only PRECOND_SOLVER DEFAULT/INVERSE_CHOLESKY")
1253 'complex preconditioner S', matrix_s)
1255 preconditioner_env%solver = solver_type
1271 matrix_t_re, matrix_t_im, &
1272 matrix_s_re, matrix_s_im, &
1273 energy_gap, solver_type)
1276 TYPE(
dbcsr_type),
POINTER :: matrix_t_re, matrix_t_im, matrix_s_re, &
1278 REAL(kind=
dp),
INTENT(IN) :: energy_gap
1279 INTEGER,
INTENT(IN) :: solver_type
1285 cpabort(
"Complex FULL_KINETIC supports only PRECOND_SOLVER DEFAULT/INVERSE_CHOLESKY")
1288 'complex preconditioner T', matrix_t)
1290 'complex preconditioner S', matrix_s)
1292 preconditioner_env%solver = solver_type
1308 TYPE(
dbcsr_type),
POINTER :: matrix_re, matrix_im
1310 CHARACTER(LEN=*),
INTENT(IN) :: matrix_name
1313 INTEGER :: ncol, nrow
1315 TYPE(
cp_fm_type) :: matrix_im_fm, matrix_re_fm
1318 cpassert(
ASSOCIATED(matrix_re))
1319 cpassert(
ASSOCIATED(matrix_im))
1320 CALL dbcsr_get_info(matrix_re, nfullrows_total=nrow, nfullcols_total=ncol)
1322 context=preconditioner_env%ctxt, &
1323 para_env=preconditioner_env%para_env)
1324 CALL cp_fm_create(matrix_re_fm, fm_struct, name=trim(matrix_name)//
' real')
1325 CALL cp_fm_create(matrix_im_fm, fm_struct, name=trim(matrix_name)//
' imaginary')
1329 CALL cp_cfm_create(matrix, matrix_re_fm%matrix_struct, name=matrix_name)
1348 INTEGER,
INTENT(IN) :: prec_type, nspins
1354 NULLIFY (para_env, blacs_env)
1355 CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
1358 SELECT CASE (prec_type)
1371 cpabort(
"Unknown preconditioner type")
1377 SELECT CASE (prec_type)
1387 para_env=para_env, &
1388 blacs_env=blacs_env)
1416 ot_preconditioner, prec_type, solver_type, &
1417 energy_gap, nspins, has_unit_metric, &
1418 convert_to_dbcsr, chol_type, full_mo_set, chebyshev_degree, &
1419 low_rank_base, fermi_low_rank_max_rank, lattice_fft, &
1420 lattice_fft_local_cells)
1423 TYPE(
mo_set_type),
DIMENSION(:),
INTENT(INOUT) :: mos
1424 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_ks, matrix_s
1426 INTEGER,
INTENT(IN) :: prec_type, solver_type
1427 REAL(
dp),
INTENT(IN) :: energy_gap
1428 INTEGER,
INTENT(IN) :: nspins
1429 LOGICAL,
INTENT(IN),
OPTIONAL :: has_unit_metric, convert_to_dbcsr
1430 INTEGER,
INTENT(IN),
OPTIONAL :: chol_type
1431 LOGICAL,
INTENT(IN),
OPTIONAL :: full_mo_set
1432 INTEGER,
INTENT(IN),
OPTIONAL :: chebyshev_degree, low_rank_base, &
1433 fermi_low_rank_max_rank, lattice_fft, &
1434 lattice_fft_local_cells
1436 CHARACTER(LEN=*),
PARAMETER :: routinen =
'prepare_preconditioner'
1438 CHARACTER(LEN=default_string_length) :: msg
1439 INTEGER :: handle, icall, ispin, my_chebyshev_degree, my_fermi_low_rank_max_rank, &
1440 my_lattice_fft, my_lattice_fft_local_cells, my_low_rank_base, n_loops
1441 INTEGER,
DIMENSION(5) :: nocc, norb
1442 INTEGER,
DIMENSION(:),
POINTER :: multiple_unit_cell
1443 LOGICAL :: do_co_rotate, do_kpoints, my_convert_to_dbcsr, my_full_mo_set, &
1444 my_has_unit_metric, use_covariant_full_all, use_mo_coeff_b
1448 TYPE(
dbcsr_type),
POINTER :: matrix_t, mo_coeff_b
1450 TYPE(
mo_set_type),
ALLOCATABLE,
DIMENSION(:) :: canonical_mos
1454 CALL timeset(routinen, handle)
1455 NULLIFY (matrix_t, mo_coeff_b, mo_coeff, kinetic, dft_control, para_env, blacs_env, &
1456 input, subsys_section, multiple_unit_cell)
1457 my_has_unit_metric = .false.
1458 IF (
PRESENT(has_unit_metric)) my_has_unit_metric = has_unit_metric
1459 my_convert_to_dbcsr = .true.
1460 IF (
PRESENT(convert_to_dbcsr)) my_convert_to_dbcsr = convert_to_dbcsr
1461 my_full_mo_set = .false.
1462 IF (
PRESENT(full_mo_set)) my_full_mo_set = full_mo_set
1463 my_chebyshev_degree = 8
1464 IF (
PRESENT(chebyshev_degree)) my_chebyshev_degree = chebyshev_degree
1466 IF (
PRESENT(low_rank_base)) my_low_rank_base = low_rank_base
1467 my_fermi_low_rank_max_rank = 48
1468 IF (
PRESENT(fermi_low_rank_max_rank)) my_fermi_low_rank_max_rank = fermi_low_rank_max_rank
1470 IF (
PRESENT(lattice_fft)) my_lattice_fft = lattice_fft
1471 my_lattice_fft_local_cells = 0
1472 IF (
PRESENT(lattice_fft_local_cells)) my_lattice_fft_local_cells = lattice_fft_local_cells
1473 IF (my_lattice_fft_local_cells < 0) cpabort(
"LATTICE_FFT_LOCAL_CELLS must not be negative")
1474 do_kpoints = .false.
1478 dft_control=dft_control, &
1479 do_kpoints=do_kpoints, &
1481 para_env=para_env, &
1482 blacs_env=blacs_env)
1486 cpabort(
"FERMI_LOW_RANK_BASE LATTICE_FFT requires PRECONDITIONER FERMI_LOW_RANK")
1490 cpabort(
"Unknown FERMI_LOW_RANK_BASE setting")
1496 cpabort(
"Unknown LATTICE_FFT setting")
1498 IF (my_lattice_fft_local_cells > 0 .AND. my_lattice_fft /=
ot_lattice_fft_on)
THEN
1499 cpabort(
"LATTICE_FFT_LOCAL_CELLS requires LATTICE_FFT ON")
1502 SELECT CASE (prec_type)
1506 cpabort(
"LATTICE_FFT does not support the selected OT preconditioner")
1510 cpabort(
"LATTICE_FFT requires PRECOND_SOLVER DEFAULT or INVERSE_CHOLESKY")
1512 IF (my_has_unit_metric .OR. do_kpoints .OR. .NOT.
ASSOCIATED(input))
THEN
1514 cpabort(
"LATTICE_FFT ON requires a non-unit metric in a real Gamma-point calculation")
1521 IF (.NOT.
ASSOCIATED(subsys_section))
THEN
1522 IF (my_lattice_fft ==
ot_lattice_fft_on) cpabort(
"LATTICE_FFT ON requires a SUBSYS section")
1527 i_vals=multiple_unit_cell)
1528 IF (.NOT.
ASSOCIATED(multiple_unit_cell))
THEN
1530 cpabort(
"LATTICE_FFT ON requires a valid CELL%MULTIPLE_UNIT_CELL")
1534 IF (
SIZE(multiple_unit_cell) /= 3 .OR. any(multiple_unit_cell <= 0))
THEN
1536 cpabort(
"LATTICE_FFT ON requires a valid CELL%MULTIPLE_UNIT_CELL")
1539 ELSE IF (product(multiple_unit_cell) <= 1 .AND. my_lattice_fft ==
ot_lattice_fft_on)
THEN
1540 cpabort(
"LATTICE_FFT ON requires an explicitly replicated multiple unit cell")
1542 IF (my_lattice_fft_local_cells >= product(multiple_unit_cell))
THEN
1543 cpabort(
"LATTICE_FFT_LOCAL_CELLS must be smaller than the replicated cell count")
1549 IF (dft_control%qs_control%semi_empirical .OR. dft_control%qs_control%dftb .OR. &
1550 dft_control%qs_control%xtb)
THEN
1552 msg =
"Full_kinetic not available for semi-empirical methods"
1555 matrix_t => matrix_s(1)%matrix
1557 cpassert(.NOT. my_has_unit_metric)
1559 matrix_t => kinetic(1)%matrix
1565 IF (my_full_mo_set)
THEN
1566 DO ispin = 1, nspins
1567 CALL get_mo_set(mo_set=mos(ispin), homo=nocc(ispin), nmo=norb(ispin))
1568 CALL set_mo_set(mo_set=mos(ispin), homo=norb(ispin))
1575 SELECT CASE (prec_type)
1580 do_co_rotate =
ASSOCIATED(qs_env%mo_derivs)
1581 DO ispin = 1, nspins
1582 CALL get_mo_set(mo_set=mos(ispin), mo_coeff_b=mo_coeff_b, mo_coeff=mo_coeff)
1583 use_mo_coeff_b = mos(ispin)%use_mo_coeff_b
1584 IF (use_mo_coeff_b .AND. do_co_rotate)
THEN
1586 do_rotation=.true., &
1587 co_rotate=qs_env%mo_derivs(ispin)%matrix, &
1588 para_env=para_env, &
1589 blacs_env=blacs_env)
1590 ELSE IF (use_mo_coeff_b)
THEN
1592 do_rotation=.true., &
1593 para_env=para_env, &
1594 blacs_env=blacs_env)
1608 ALLOCATE (canonical_mos(nspins))
1609 DO ispin = 1, nspins
1611 CALL get_mo_set(mo_set=canonical_mos(ispin), mo_coeff_b=mo_coeff_b, mo_coeff=mo_coeff)
1612 IF (canonical_mos(ispin)%use_mo_coeff_b)
THEN
1614 canonical_mos(ispin)%use_mo_coeff_b = .false.
1616 CALL canonicalize_full_all_copy(ot_preconditioner(ispin)%preconditioner, &
1617 mo_coeff, matrix_ks(ispin)%matrix, &
1618 canonical_mos(ispin)%homo)
1625 SELECT CASE (prec_type)
1627 DO ispin = 1,
SIZE(ot_preconditioner)
1628 ot_preconditioner(ispin)%preconditioner%in_use = 0
1631 DO icall = 1, n_loops
1632 ot_preconditioner(icall)%preconditioner%polynomial_degree = my_chebyshev_degree
1633 ot_preconditioner(icall)%preconditioner%low_rank_base = my_low_rank_base
1634 ot_preconditioner(icall)%preconditioner%lattice_fft_mode = my_lattice_fft
1635 ot_preconditioner(icall)%preconditioner%lattice_local_cells = my_lattice_fft_local_cells
1636 ot_preconditioner(icall)%preconditioner%lattice_dims = [1, 1, 1]
1638 cpassert(
ASSOCIATED(multiple_unit_cell))
1639 ot_preconditioner(icall)%preconditioner%lattice_dims = multiple_unit_cell
1641 ot_preconditioner(icall)%preconditioner%spectral_max_rank = my_fermi_low_rank_max_rank
1642 IF (my_has_unit_metric)
THEN
1643 IF (use_covariant_full_all)
THEN
1645 prec_type, solver_type, &
1646 matrix_h=matrix_ks(icall)%matrix, &
1647 mo_set=canonical_mos(icall), &
1648 energy_gap=energy_gap, &
1649 convert_precond_to_dbcsr=my_convert_to_dbcsr)
1652 prec_type, solver_type, &
1653 matrix_h=matrix_ks(icall)%matrix, &
1654 mo_set=mos(icall), &
1655 energy_gap=energy_gap, &
1656 convert_precond_to_dbcsr=my_convert_to_dbcsr)
1659 IF (use_covariant_full_all)
THEN
1661 prec_type, solver_type, &
1662 matrix_h=matrix_ks(icall)%matrix, &
1663 matrix_s=matrix_s(1)%matrix, matrix_t=matrix_t, &
1664 mo_set=canonical_mos(icall), &
1665 energy_gap=energy_gap, &
1666 convert_precond_to_dbcsr=my_convert_to_dbcsr, chol_type=chol_type)
1669 prec_type, solver_type, &
1670 matrix_h=matrix_ks(icall)%matrix, &
1671 matrix_s=matrix_s(1)%matrix, matrix_t=matrix_t, &
1672 mo_set=mos(icall), energy_gap=energy_gap, &
1673 convert_precond_to_dbcsr=my_convert_to_dbcsr, chol_type=chol_type)
1679 IF (
ALLOCATED(canonical_mos))
THEN
1680 DO ispin = 1,
SIZE(canonical_mos)
1683 DEALLOCATE (canonical_mos)
1687 IF (my_full_mo_set)
THEN
1688 DO ispin = 1, nspins
1689 CALL set_mo_set(mo_set=mos(ispin), homo=nocc(ispin))
1693 CALL timestop(handle)
1704 SUBROUTINE canonicalize_full_all_copy(preconditioner_env, mo_coeff, matrix_h, nocc)
1709 INTEGER,
INTENT(IN) :: nocc
1711 CHARACTER(LEN=*),
PARAMETER :: routinen =
'canonicalize_full_all_copy'
1713 INTEGER :: handle, nao
1714 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: occupied_evals
1716 TYPE(
cp_fm_type) :: canonical_coeff, h_block, weighted_coeff
1718 CALL timeset(routinen, handle)
1723 context=preconditioner_env%ctxt, &
1724 para_env=preconditioner_env%para_env)
1725 CALL cp_fm_create(canonical_coeff, fm_struct, name=routinen)
1726 CALL cp_fm_create(weighted_coeff, fm_struct, name=routinen)
1731 context=preconditioner_env%ctxt, &
1732 para_env=preconditioner_env%para_env)
1734 IF (
ASSOCIATED(preconditioner_env%occ_rotation_dbcsr))
THEN
1737 IF (
ASSOCIATED(preconditioner_env%occ_rotation))
THEN
1739 DEALLOCATE (preconditioner_env%occ_rotation)
1741 ALLOCATE (preconditioner_env%occ_rotation)
1742 CALL cp_fm_create(preconditioner_env%occ_rotation, fm_struct, name=
"occupied rotation")
1746 CALL parallel_gemm(
'T',
'N', nocc, nocc, nao, 1.0_dp, canonical_coeff, &
1747 weighted_coeff, 0.0_dp, h_block)
1748 ALLOCATE (occupied_evals(nocc))
1751 CALL parallel_gemm(
'N',
'N', nao, nocc, nocc, 1.0_dp, canonical_coeff, &
1752 preconditioner_env%occ_rotation, 0.0_dp, weighted_coeff)
1753 CALL cp_fm_to_fm(weighted_coeff, mo_coeff, nocc, 1, 1)
1755 DEALLOCATE (occupied_evals)
1759 CALL timestop(handle)
1761 END SUBROUTINE canonicalize_full_all_copy
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
methods related to the blacs parallel environment
Represents a complex full matrix distributed on many processors.
subroutine, public cp_cfm_release(matrix)
Releases a full matrix.
subroutine, public cp_fm_to_cfm(msourcer, msourcei, mtarget)
Construct a complex full matrix by taking its real and imaginary parts from two separate real-value f...
subroutine, public cp_cfm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
Creates a new full matrix with the given structure.
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_release_p(matrix)
...
subroutine, public dbcsr_get_info(matrix, nblkrows_total, nblkcols_total, nfullrows_total, nfullcols_total, nblkrows_local, nblkcols_local, nfullrows_local, nfullcols_local, my_prow, my_pcol, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, row_blk_offset, col_blk_offset, distribution, name, matrix_type, group)
...
DBCSR operations in CP2K.
subroutine, public cp_dbcsr_sm_fm_multiply(matrix, fm_in, fm_out, ncol, alpha, beta)
multiply a dbcsr with a fm matrix
subroutine, public copy_dbcsr_to_fm(matrix, fm, plan, check_plan)
Copy a DBCSR matrix to a BLACS matrix.
Basic linear algebra operations for full matrices.
subroutine, public cp_fm_uplo_to_full(matrix, work, uplo)
given a triangular matrix according to uplo, computes the corresponding full matrix
various cholesky decomposition related routines
subroutine, public cp_fm_cholesky_invert(matrix, n, info_out, work)
Replace the upper Cholesky factor by the upper triangle of the inverse. When work is provided,...
subroutine, public cp_fm_cholesky_decompose(matrix, n, info_out)
used to replace a symmetric positive def. matrix M with its cholesky decomposition U: M = U^T * U,...
used for collecting some of the diagonalization schemes available for cp_fm_type. cp_fm_power also mo...
subroutine, public choose_eigv_solver(matrix, eigenvectors, eigenvalues, info)
Choose the Eigensolver depending on which library is available ELPA seems to be unstable for small sy...
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
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
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
creates a new full matrix with the given structure
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...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
Block-circulant inverse operators for replicated-cell OT preconditioners.
real(kind=dp), parameter, public lattice_fft_auto_max_cost_ratio
subroutine, public build_lattice_local_correction(operator_matrix, lattice_dims, local_cell_count, correction_indices, operator_columns, coarse_inverse, corrected_projection_error, info)
Build a balanced local correction for selected non-circulant cell blocks.
subroutine, public build_lattice_inverse(operator_matrix, lattice_dims, inverse_k, projection_error, used_fft, info)
Project a cell-major SPD operator onto lattice translations and invert its Fourier blocks.
pure real(kind=dp) function, public lattice_local_storage_ratio(lattice_dims, operator_count, local_cell_count)
Estimate balanced-local-correction storage relative to one dense real operator.
pure real(kind=dp) function, public lattice_fft_storage_ratio(lattice_dims, operator_count)
Estimate reciprocal-block storage relative to one dense real operator.
pure logical function, public lattice_fft_auto_select(lattice_dims, block_size, rhs_count, operator_count, num_pe, projection_error, used_fft, info)
Conservative error-, work-, and storage-aware AUTO selector.
subroutine, public lattice_grid(lattice_dims, index_to_cell, xkp)
Enumerate a regular direct/reciprocal lattice with the first direction varying fastest.
integer, parameter, public lattice_fft_auto_min_cells
subroutine, public build_lattice_inverse_from_blocks(blocks, lattice_dims, inverse_k, used_fft, info)
Transform and invert already projected real-space lattice blocks.
pure real(kind=dp) function, public lattice_local_cost_ratio(lattice_dims, local_cell_count)
Estimate balanced-local-correction work relative to a dense inverse application.
pure real(kind=dp) function, public lattice_fft_cost_ratio(lattice_dims, block_size, rhs_count, num_pe)
Estimate lattice-FFT application work relative to a dense inverse application.
real(kind=dp), parameter, public lattice_fft_auto_max_storage_ratio
Small algebraic helpers for the rotationally covariant low-rank OT preconditioner.
pure elemental real(kind=dp) function, public low_rank_inverse_weight(eigenvalue, reference, energy_gap)
Spectral inverse weight relative to a common occupied reference level.
pure integer function, public low_rank_select_rank(eigenvalues, nocc, max_rank, degeneracy_tolerance)
Select a bounded spectral rank without cutting a degenerate boundary manifold.
Interface to the message passing library MPI.
basic linear algebra operations for full matrixes
computes preconditioners, and implements methods to apply them currently used in qs_ot
subroutine, public apply_preconditioner_dbcsr_complex(preconditioner_env, matrix_in_re, matrix_in_im, matrix_out_re, matrix_out_im)
Apply a complex orbital preconditioner to paired real/imaginary DBCSR matrices.
subroutine, public apply_preconditioner_fm(preconditioner_env, matrix_in, matrix_out)
applies a previously created preconditioner to a full matrix
subroutine, public apply_preconditioner_cfm_complex(preconditioner_env, matrix_in, matrix_out)
Apply a complex k-point orbital preconditioner.
subroutine, public apply_preconditioner_dbcsr(preconditioner_env, matrix_in, matrix_out)
...
computes preconditioners, and implements methods to apply them currently used in qs_ot
subroutine, public make_complex_full_single_inverse(preconditioner_env, matrix_c0, matrix_h, matrix_s, energy_gap)
Build a gauge-covariant FULL_SINGLE_INVERSE operator for a complex k-point channel.
subroutine, public make_complex_full_kinetic(preconditioner_env, matrix_t, matrix_s, energy_gap)
Build the inverse complex kinetic-plus-overlap preconditioner.
subroutine, public make_complex_full_s_inverse(preconditioner_env, matrix_s)
Build the inverse complex overlap preconditioner.
subroutine, public make_complex_full_all_covariant(preconditioner_env, matrix_c0, matrix_h, matrix_s, energy_gap, occupation_signature)
Build the gauge-covariant FULL_ALL inverse for a complex k-point channel.
subroutine, public make_complex_full_single(preconditioner_env, matrix_h, matrix_s, energy_homo, energy_gap)
Build the complex spectral FULL_SINGLE preconditioner.
subroutine, public make_complex_fermi_low_rank(preconditioner_env, matrix_c0, matrix_h, matrix_s, energy_gap, max_rank, spectral_window, degeneracy_tolerance)
Build the bounded low-rank spectral inverse for a complex k-point channel.
subroutine, public make_preconditioner_matrix(preconditioner_env, matrix_h, matrix_s, matrix_t, mo_coeff, energy_homo, eigenvalues_ot, energy_gap, my_solver_type)
...
subroutine, public make_complex_full_all(preconditioner_env, matrix_c0, matrix_h, matrix_s, c0_evals, energy_gap)
Build the state-selective FULL_ALL operator for a complex k-point channel. The occupied/reference sub...
solves the preconditioner, contains to utility function for fm<->dbcsr transfers, should be moved soo...
subroutine, public transfer_dbcsr_to_fm(dbcsr_matrix, fm_matrix, para_env, context)
transfers a dbcsr to a full matrix
subroutine, public solve_preconditioner(my_solver_type, preconditioner_env, matrix_s, matrix_h)
...
subroutine, public transfer_fm_to_dbcsr(fm_matrix, dbcsr_matrix, template_mat)
transfers a full matrix to a dbcsr
subroutine, public init_preconditioner(preconditioner_env, para_env, blacs_env)
...
subroutine, public destroy_preconditioner(preconditioner_env)
...
computes preconditioners, and implements methods to apply them currently used in qs_ot
subroutine, public make_preconditioner_complex_full_all(preconditioner_env, matrix_c_re, matrix_c_im, matrix_h_re, matrix_h_im, matrix_s_re, matrix_s_im, mo_set, energy_gap, solver_type)
Construct FULL_ALL directly from one complex H(k), S(k), and C(k) channel.
subroutine, public make_preconditioner_complex_full_s_inverse(preconditioner_env, matrix_s_re, matrix_s_im, solver_type)
Construct a complex FULL_S_INVERSE preconditioner.
subroutine, public make_preconditioner_complex_full_single(preconditioner_env, matrix_h_re, matrix_h_im, matrix_s_re, matrix_s_im, mo_set, energy_gap, solver_type)
Construct a complex FULL_SINGLE preconditioner from H(k) and S(k).
subroutine, public dbcsr_pair_to_cfm(matrix_re, matrix_im, preconditioner_env, matrix_name, matrix)
Copy a real/imaginary DBCSR pair to one distributed complex full matrix.
subroutine, public make_preconditioner_complex_full_single_inverse(preconditioner_env, matrix_c_re, matrix_c_im, matrix_h_re, matrix_h_im, matrix_s_re, matrix_s_im, energy_gap, solver_type)
Construct a complex FULL_SINGLE_INVERSE preconditioner without discarding Im(H,S,C).
subroutine, public make_preconditioner_complex_full_all_covariant(preconditioner_env, matrix_c_re, matrix_c_im, matrix_h_re, matrix_h_im, matrix_s_re, matrix_s_im, energy_gap, solver_type, occupation_signature)
Construct rotation-covariant FULL_ALL for one complex k-point channel.
subroutine, public restart_preconditioner(qs_env, preconditioner, prec_type, nspins)
Allows for a restart of the preconditioner depending on the method it purges all arrays or keeps them...
subroutine, public prepare_preconditioner(qs_env, mos, matrix_ks, matrix_s, ot_preconditioner, prec_type, solver_type, energy_gap, nspins, has_unit_metric, convert_to_dbcsr, chol_type, full_mo_set, chebyshev_degree, low_rank_base, fermi_low_rank_max_rank, lattice_fft, lattice_fft_local_cells)
...
subroutine, public make_preconditioner_complex_fermi_low_rank(preconditioner_env, matrix_c_re, matrix_c_im, matrix_h_re, matrix_h_im, matrix_s_re, matrix_s_im, energy_gap, max_rank, solver_type)
Construct FERMI_LOW_RANK directly for one complex k-point channel.
subroutine, public make_preconditioner_complex_full_kinetic(preconditioner_env, matrix_t_re, matrix_t_im, matrix_s_re, matrix_s_im, energy_gap, solver_type)
Construct a complex FULL_KINETIC preconditioner.
subroutine, public make_preconditioner(preconditioner_env, precon_type, solver_type, matrix_h, matrix_s, matrix_t, mo_set, energy_gap, convert_precond_to_dbcsr, chol_type)
...
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, matrix_vhxc, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
collects routines that perform operations directly related to MOs
Definition and initialisation of the mo data type.
subroutine, public duplicate_mo_set(mo_set_new, mo_set_old)
allocate a new mo_set, and copy the old data
subroutine, public set_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, uniform_occupation, kts, mu, flexible_electron_count)
Set the components of a MO set data structure.
subroutine, public deallocate_mo_set(mo_set)
Deallocate a wavefunction data structure.
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kts, mu, flexible_electron_count, cmo_coeff)
Get the components of a MO set data structure.
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
Represent a complex full matrix.
keeps the information about the structure of a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...
stores all the informations relevant to an mpi environment