57#include "./base/base_uses.f90"
62 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'preconditioner_apply'
78 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_in, matrix_out
80 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_preconditioner_fm'
84 CALL timeset(routinen, handle)
86 SELECT CASE (preconditioner_env%in_use)
88 cpabort(
"No preconditioner in use")
90 CALL apply_full_single(preconditioner_env, matrix_in, matrix_out)
92 CALL apply_full_all(preconditioner_env, matrix_in, matrix_out)
94 CALL apply_low_rank_fm(preconditioner_env, matrix_in, matrix_out)
96 CALL apply_full_all_covariant(preconditioner_env, matrix_in, matrix_out)
98 IF (preconditioner_env%lattice_fft_active)
THEN
99 CALL apply_lattice_operator_fm(preconditioner_env, matrix_in, matrix_out)
101 SELECT CASE (preconditioner_env%solver)
103 CALL apply_full_single(preconditioner_env, matrix_in, matrix_out)
105 CALL apply_full_direct(preconditioner_env, matrix_in, matrix_out)
107 CALL apply_chebyshev_fm(preconditioner_env, matrix_in, matrix_out)
109 cpabort(
"Solver not implemented")
113 cpabort(
"Unknown preconditioner")
116 CALL timestop(handle)
131 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_preconditioner_dbcsr'
135 CALL timeset(routinen, handle)
137 SELECT CASE (preconditioner_env%in_use)
139 cpabort(
"No preconditioner in use")
141 CALL apply_single(preconditioner_env, matrix_in, matrix_out)
143 CALL apply_all(preconditioner_env, matrix_in, matrix_out)
145 CALL apply_low_rank_dbcsr(preconditioner_env, matrix_in, matrix_out)
147 CALL apply_all_covariant(preconditioner_env, matrix_in, matrix_out)
149 IF (preconditioner_env%lattice_fft_active)
THEN
150 CALL apply_lattice_operator_dbcsr(preconditioner_env, matrix_in, matrix_out)
152 SELECT CASE (preconditioner_env%solver)
154 CALL apply_single(preconditioner_env, matrix_in, matrix_out)
156 cpabort(
"Apply_full_direct not supported with ot")
159 CALL apply_chebyshev_dbcsr(preconditioner_env, matrix_in, matrix_out)
161 cpabort(
"Wrong solver")
165 cpabort(
"Wrong preconditioner")
168 CALL timestop(handle)
181 TYPE(
cp_cfm_type),
INTENT(IN) :: matrix_in, matrix_out
183 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_preconditioner_cfm_complex'
185 INTEGER :: handle, k, n, npre
188 CALL timeset(routinen, handle)
190 SELECT CASE (preconditioner_env%in_use)
195 cpabort(
"Unsupported complex K-point OT preconditioner")
197 cpassert(
ASSOCIATED(preconditioner_env%complex_fm))
202 SELECT CASE (preconditioner_env%in_use)
204 CALL apply_complex_full_all_spectral(preconditioner_env, matrix_in, matrix_out)
206 cpassert(
ASSOCIATED(preconditioner_env%occ_rotation_complex))
208 name=
'complex covariant FULL_ALL input')
209 CALL cp_cfm_create(canonical_out, matrix_out%matrix_struct, &
210 name=
'complex covariant FULL_ALL output')
212 preconditioner_env%occ_rotation_complex,
z_zero, canonical_in)
213 CALL apply_complex_full_all_spectral(preconditioner_env, canonical_in, canonical_out)
215 preconditioner_env%occ_rotation_complex,
z_zero, matrix_out)
219 CALL apply_complex_fermi_low_rank(preconditioner_env, matrix_in, matrix_out)
222 matrix_in,
z_zero, matrix_out)
225 CALL timestop(handle)
235 SUBROUTINE apply_complex_full_all_spectral(preconditioner_env, matrix_in, matrix_out)
238 TYPE(
cp_cfm_type),
INTENT(IN) :: matrix_in, matrix_out
240 COMPLEX(KIND=dp),
CONTIGUOUS,
DIMENSION(:, :), &
241 POINTER :: local_data
242 INTEGER :: i, j, k, n, ncol_local, nrow_local
243 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
244 REAL(kind=
dp) :: scale
247 cpassert(
ASSOCIATED(preconditioner_env%full_evals))
248 cpassert(
ASSOCIATED(preconditioner_env%occ_evals))
250 cpassert(n ==
SIZE(preconditioner_env%full_evals))
251 cpassert(k ==
SIZE(preconditioner_env%occ_evals))
252 CALL cp_cfm_create(matrix_spectral, matrix_in%matrix_struct, &
253 name=
'complex FULL_ALL spectral input')
255 matrix_in,
z_zero, matrix_spectral)
256 CALL cp_cfm_get_info(matrix_spectral, nrow_local=nrow_local, ncol_local=ncol_local, &
257 row_indices=row_indices, col_indices=col_indices, local_data=local_data)
260 scale = 1.0_dp/max(preconditioner_env%energy_gap, &
261 preconditioner_env%full_evals(row_indices(i)) - &
262 preconditioner_env%occ_evals(col_indices(j)))
263 local_data(i, j) = scale*local_data(i, j)
267 matrix_spectral,
z_zero, matrix_out)
270 END SUBROUTINE apply_complex_full_all_spectral
278 SUBROUTINE apply_complex_fermi_low_rank(preconditioner_env, matrix_in, matrix_out)
281 TYPE(
cp_cfm_type),
INTENT(IN) :: matrix_in, matrix_out
283 COMPLEX(KIND=dp),
CONTIGUOUS,
DIMENSION(:, :), &
284 POINTER :: local_data
285 INTEGER :: i, j, k, n, ncol_local, nocc, &
286 nrow_local, rank_used
287 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
288 REAL(kind=
dp) :: scale
291 cpassert(
ASSOCIATED(preconditioner_env%complex_fm))
292 cpassert(
ASSOCIATED(preconditioner_env%full_evals))
293 cpassert(
ASSOCIATED(preconditioner_env%occ_evals))
295 nocc =
SIZE(preconditioner_env%occ_evals)
296 rank_used = min(preconditioner_env%spectral_rank, n - nocc)
297 cpassert(n ==
SIZE(preconditioner_env%full_evals))
299 CALL cp_cfm_create(matrix_spectral, matrix_in%matrix_struct, &
300 name=
'complex FERMI_LOW_RANK spectral input')
302 matrix_in,
z_zero, matrix_spectral)
303 CALL cp_cfm_get_info(matrix_spectral, nrow_local=nrow_local, ncol_local=ncol_local, &
304 row_indices=row_indices, col_indices=col_indices, local_data=local_data)
307 scale = preconditioner_env%spectral_base_scale
308 IF (row_indices(i) > nocc .AND. row_indices(i) <= nocc + rank_used)
THEN
310 preconditioner_env%full_evals(row_indices(i)), &
311 preconditioner_env%spectral_reference, preconditioner_env%energy_gap)
313 local_data(i, j) = scale*local_data(i, j)
317 matrix_spectral,
z_zero, matrix_out)
320 END SUBROUTINE apply_complex_fermi_low_rank
331 matrix_out_re, matrix_out_im)
334 TYPE(
dbcsr_type) :: matrix_in_re, matrix_in_im, &
335 matrix_out_re, matrix_out_im
337 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_preconditioner_dbcsr_complex'
339 INTEGER :: handle, k, n
341 TYPE(
cp_fm_type) :: matrix_in_im_fm, matrix_in_re_fm, &
342 matrix_out_im_fm, matrix_out_re_fm
344 CALL timeset(routinen, handle)
346 CALL dbcsr_get_info(matrix_in_re, nfullrows_total=n, nfullcols_total=k)
347 cpassert(
ASSOCIATED(preconditioner_env%complex_fm))
349 CALL cp_fm_create(matrix_in_re_fm, preconditioner_env%complex_fm%matrix_struct, &
350 nrow=n, ncol=k, name=
'complex preconditioner input real')
351 CALL cp_fm_create(matrix_in_im_fm, preconditioner_env%complex_fm%matrix_struct, &
352 nrow=n, ncol=k, name=
'complex preconditioner input imaginary')
353 CALL cp_fm_create(matrix_out_re_fm, preconditioner_env%complex_fm%matrix_struct, &
354 nrow=n, ncol=k, name=
'complex preconditioner output real')
355 CALL cp_fm_create(matrix_out_im_fm, preconditioner_env%complex_fm%matrix_struct, &
356 nrow=n, ncol=k, name=
'complex preconditioner output imaginary')
360 CALL cp_cfm_create(matrix_in, matrix_in_re_fm%matrix_struct, &
361 name=
'complex preconditioner input')
362 CALL cp_cfm_create(matrix_out, matrix_in_re_fm%matrix_struct, &
363 name=
'complex preconditioner output')
364 CALL cp_fm_to_cfm(matrix_in_re_fm, matrix_in_im_fm, matrix_in)
366 CALL cp_cfm_to_fm(matrix_out, matrix_out_re_fm, matrix_out_im_fm)
379 CALL timestop(handle)
389 SUBROUTINE apply_full_single(preconditioner_env, matrix_in, matrix_out)
392 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_in, matrix_out
394 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_full_single'
396 INTEGER :: handle, k, n
398 CALL timeset(routinen, handle)
401 CALL parallel_gemm(
'N',
'N', n, k, n, 1.0_dp, preconditioner_env%fm, &
402 matrix_in, 0.0_dp, matrix_out)
403 CALL timestop(handle)
405 END SUBROUTINE apply_full_single
413 SUBROUTINE apply_single(preconditioner_env, matrix_in, matrix_out)
418 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_single'
422 CALL timeset(routinen, handle)
424 IF (.NOT.
ASSOCIATED(preconditioner_env%dbcsr_matrix))
THEN
425 cpabort(
"NOT ASSOCIATED preconditioner_env%dbcsr_matrix")
427 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, preconditioner_env%dbcsr_matrix, matrix_in, &
430 CALL timestop(handle)
432 END SUBROUTINE apply_single
441 SUBROUTINE apply_full_direct(preconditioner_env, matrix_in, matrix_out)
444 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_in, matrix_out
446 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_full_direct'
448 INTEGER :: handle, k, n
451 CALL timeset(routinen, handle)
454 CALL cp_fm_create(work, matrix_in%matrix_struct, name=
"apply_full_single")
456 &
"SOLVE", transa=
"T")
458 &
"SOLVE", transa=
"N")
461 CALL timestop(handle)
463 END SUBROUTINE apply_full_direct
471 SUBROUTINE apply_chebyshev_fm(preconditioner_env, matrix_in, matrix_out)
474 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_in, matrix_out
476 INTEGER ::
degree, iteration, k, n
477 REAL(kind=
dp) :: delta, rho, rho_previous, sigma, theta
480 cpassert(
ASSOCIATED(preconditioner_env%fm))
481 degree = preconditioner_env%polynomial_degree
483 theta = 0.5_dp*(preconditioner_env%polynomial_max + preconditioner_env%polynomial_min)
484 delta = 0.5_dp*(preconditioner_env%polynomial_max - preconditioner_env%polynomial_min)
486 rho_previous = 1.0_dp/sigma
488 CALL cp_fm_create(direction, matrix_in%matrix_struct, name=
'Chebyshev direction')
489 CALL cp_fm_create(residual, matrix_in%matrix_struct, name=
'Chebyshev residual')
495 CALL parallel_gemm(
'N',
'N', n, k, n, -1.0_dp, preconditioner_env%fm, &
496 matrix_out, 1.0_dp, residual)
497 rho = 1.0_dp/(2.0_dp*sigma - rho_previous)
506 END SUBROUTINE apply_chebyshev_fm
514 SUBROUTINE apply_chebyshev_dbcsr(preconditioner_env, matrix_in, matrix_out)
519 INTEGER ::
degree, iteration
520 REAL(kind=
dp) :: delta, rho, rho_previous, sigma, theta
523 cpassert(
ASSOCIATED(preconditioner_env%dbcsr_matrix))
524 degree = preconditioner_env%polynomial_degree
526 theta = 0.5_dp*(preconditioner_env%polynomial_max + preconditioner_env%polynomial_min)
527 delta = 0.5_dp*(preconditioner_env%polynomial_max - preconditioner_env%polynomial_min)
529 rho_previous = 1.0_dp/sigma
530 CALL dbcsr_copy(direction, matrix_in, name=
'Chebyshev direction')
531 CALL dbcsr_copy(residual, matrix_in, name=
'Chebyshev residual')
533 CALL dbcsr_add(matrix_out, direction, 1.0_dp, 1.0_dp/theta)
535 CALL dbcsr_add(direction, matrix_in, 1.0_dp, 1.0_dp/theta)
538 CALL dbcsr_add(residual, matrix_in, 1.0_dp, 1.0_dp)
539 CALL dbcsr_multiply(
'N',
'N', -1.0_dp, preconditioner_env%dbcsr_matrix, &
540 matrix_out, 1.0_dp, residual)
541 rho = 1.0_dp/(2.0_dp*sigma - rho_previous)
542 CALL dbcsr_add(direction, residual, rho*rho_previous, 2.0_dp*rho/delta)
543 CALL dbcsr_add(matrix_out, direction, 1.0_dp, 1.0_dp)
549 END SUBROUTINE apply_chebyshev_dbcsr
557 SUBROUTINE apply_low_rank_fm(preconditioner_env, matrix_in, matrix_out)
560 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_in, matrix_out
562 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_low_rank_fm'
564 INTEGER :: handle, i, j, k, n, ncol_local, nocc, &
565 nrow_local, rank_used
566 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
567 REAL(kind=
dp) :: correction
568 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
569 POINTER :: local_data
572 CALL timeset(routinen, handle)
574 cpassert(
ASSOCIATED(preconditioner_env%fm))
575 cpassert(
ASSOCIATED(preconditioner_env%full_evals))
576 cpassert(
ASSOCIATED(preconditioner_env%occ_evals))
579 nocc =
SIZE(preconditioner_env%occ_evals)
580 cpassert(n ==
SIZE(preconditioner_env%full_evals))
581 rank_used = min(preconditioner_env%spectral_rank, n - nocc)
588 SELECT CASE (preconditioner_env%low_rank_base)
590 cpassert(
ASSOCIATED(preconditioner_env%base_fm))
591 CALL parallel_gemm(
'N',
'N', n, k, n, preconditioner_env%spectral_base_scale, &
592 preconditioner_env%base_fm, matrix_in, 0.0_dp, matrix_out)
594 CALL apply_lattice_operator_fm(preconditioner_env, matrix_in, matrix_out, &
595 preconditioner_env%spectral_base_scale)
597 cpabort(
"Unknown FERMI_LOW_RANK base operator during application")
600 IF (rank_used > 0)
THEN
601 CALL cp_fm_create(matrix_tmp, matrix_in%matrix_struct, name=routinen, &
602 nrow=rank_used, ncol=k)
603 CALL cp_fm_get_info(matrix_tmp, nrow_local=nrow_local, ncol_local=ncol_local, &
604 row_indices=row_indices, col_indices=col_indices, local_data=local_data)
606 CALL parallel_gemm(
'T',
'N', rank_used, k, n, 1.0_dp, preconditioner_env%fm, &
607 matrix_in, 0.0_dp, matrix_tmp, a_first_col=nocc + 1)
612 preconditioner_env%full_evals(nocc + row_indices(i)), &
613 preconditioner_env%spectral_reference, &
614 preconditioner_env%energy_gap) &
615 - preconditioner_env%spectral_base_scale
616 local_data(i, j) = local_data(i, j)*correction
620 CALL parallel_gemm(
'N',
'N', n, k, rank_used, 1.0_dp, preconditioner_env%fm, &
621 matrix_tmp, 1.0_dp, matrix_out, a_first_col=nocc + 1)
625 CALL timestop(handle)
627 END SUBROUTINE apply_low_rank_fm
636 SUBROUTINE apply_lattice_operator_fm(preconditioner_env, matrix_in, matrix_out, scale_factor)
639 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_in, matrix_out
640 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: scale_factor
642 CHARACTER(LEN=*),
PARAMETER :: routinen =
'apply_lattice_operator_fm'
644 INTEGER :: fft_ok, handle, i
646 REAL(kind=
dp) :: imaginary_residual, output_max, scale
647 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: base_input, coarse_projected, &
648 coarse_residual, coarse_rhs, &
649 local_input, local_output
651 CALL timeset(routinen, handle)
652 cpassert(
ALLOCATED(preconditioner_env%lattice_inverse_k))
654 IF (
PRESENT(scale_factor)) scale = scale_factor
655 CALL distribute_lattice_rhs(preconditioner_env, matrix_in, &
656 preconditioner_env%lattice_rhs_distribution, local_input)
657 ALLOCATE (local_output(
SIZE(local_input, 1),
SIZE(local_input, 2)))
658 IF (
ALLOCATED(preconditioner_env%lattice_local_indices))
THEN
659 cpassert(
ALLOCATED(preconditioner_env%lattice_local_operator))
660 cpassert(
ALLOCATED(preconditioner_env%lattice_local_coarse_inverse))
661 ALLOCATE (base_input(
SIZE(local_input, 1),
SIZE(local_input, 2)), &
662 coarse_projected(
SIZE(preconditioner_env%lattice_local_indices),
SIZE(local_input, 2)), &
663 coarse_rhs(
SIZE(preconditioner_env%lattice_local_indices),
SIZE(local_input, 2)))
664 DO i = 1,
SIZE(preconditioner_env%lattice_local_indices)
665 coarse_projected(i, :) = local_input(preconditioner_env%lattice_local_indices(i), :)
667 coarse_rhs(:, :) = matmul(preconditioner_env%lattice_local_coarse_inverse, &
669 base_input(:, :) = local_input - &
670 matmul(preconditioner_env%lattice_local_operator, coarse_rhs)
672 ALLOCATE (base_input(
SIZE(local_input, 1),
SIZE(local_input, 2)), source=local_input)
675 imaginary_residual = 0.0_dp
676 IF (
SIZE(local_input, 2) > 0)
THEN
678 preconditioner_env%lattice_dims, base_input, local_output, &
679 used_fft, imaginary_residual)
681 IF (
ALLOCATED(preconditioner_env%lattice_local_indices))
THEN
682 ALLOCATE (coarse_residual(
SIZE(coarse_rhs, 1),
SIZE(coarse_rhs, 2)))
683 coarse_projected(:, :) = matmul(transpose(preconditioner_env%lattice_local_operator), &
685 coarse_residual(:, :) = matmul(preconditioner_env%lattice_local_coarse_inverse, &
687 local_output(preconditioner_env%lattice_local_indices, :) = &
688 local_output(preconditioner_env%lattice_local_indices, :) + coarse_rhs - coarse_residual
689 DEALLOCATE (coarse_projected, coarse_residual, coarse_rhs)
691 fft_ok = merge(1, 0, used_fft)
693 IF (
SIZE(local_output) > 0) output_max = maxval(abs(local_output))
694 CALL preconditioner_env%para_env%min(fft_ok)
695 CALL preconditioner_env%para_env%max(imaginary_residual)
696 CALL preconditioner_env%para_env%max(output_max)
697 IF (fft_ok == 0) cpabort(
"Lattice preconditioner inverse failed to use FFTs")
698 IF (imaginary_residual > 1.0e-10_dp*max(1.0_dp, output_max))
THEN
699 cpabort(
"Lattice preconditioner inverse produced a non-real Gamma-point result")
701 CALL collect_lattice_rhs(preconditioner_env, preconditioner_env%lattice_rhs_distribution, &
702 local_output, matrix_out, scale)
703 DEALLOCATE (base_input, local_input, local_output)
704 CALL timestop(handle)
706 END SUBROUTINE apply_lattice_operator_fm
714 SUBROUTINE apply_lattice_state_operator_fm(preconditioner_env, matrix_in, matrix_out)
717 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_in, matrix_out
719 CHARACTER(LEN=*),
PARAMETER :: routinen =
'apply_lattice_state_operator_fm'
721 INTEGER :: fft_ok, global_column, handle, i, j, k, &
724 REAL(kind=
dp) :: imaginary_residual, output_max
725 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: base_input, coarse_projected, &
726 coarse_residual, coarse_rhs, complement_input, local_input, local_output, &
727 occupied_component, occupied_update
729 CALL timeset(routinen, handle)
730 cpassert(
ALLOCATED(preconditioner_env%lattice_state_inverse_k))
732 cpassert(
SIZE(preconditioner_env%lattice_state_inverse_k, 4) == k)
733 CALL distribute_lattice_rhs(preconditioner_env, matrix_in, &
734 preconditioner_env%lattice_rhs_distribution, local_input)
735 cpassert(
ALLOCATED(preconditioner_env%lattice_occ_vectors))
736 cpassert(
ALLOCATED(preconditioner_env%lattice_occ_dual))
737 ALLOCATE (complement_input(n,
SIZE(local_input, 2)), &
738 local_output(n,
SIZE(local_input, 2)), &
739 occupied_component(k,
SIZE(local_input, 2)), &
740 occupied_update(n,
SIZE(local_input, 2)))
741 occupied_component(:, :) = matmul(transpose(preconditioner_env%lattice_occ_vectors), &
743 complement_input(:, :) = local_input - &
744 matmul(preconditioner_env%lattice_occ_dual, occupied_component)
745 ALLOCATE (base_input(n,
SIZE(local_input, 2)), source=complement_input)
746 IF (
ALLOCATED(preconditioner_env%lattice_state_local_indices))
THEN
747 cpassert(
ALLOCATED(preconditioner_env%lattice_state_local_operator))
748 cpassert(
ALLOCATED(preconditioner_env%lattice_state_local_coarse_inverse))
749 ALLOCATE (coarse_rhs(
SIZE(preconditioner_env%lattice_state_local_indices, 1), &
750 SIZE(local_input, 2)), &
751 coarse_projected(
SIZE(preconditioner_env%lattice_state_local_indices, 1), &
752 SIZE(local_input, 2)))
753 DO j = 1,
SIZE(local_input, 2)
754 state = preconditioner_env%lattice_rhs_distribution%global_columns(j)
755 DO i = 1,
SIZE(preconditioner_env%lattice_state_local_indices, 1)
756 coarse_projected(i, j) = &
757 complement_input(preconditioner_env%lattice_state_local_indices(i, state), j)
759 coarse_rhs(:, j) = matmul( &
760 preconditioner_env%lattice_state_local_coarse_inverse(:, :, state), &
761 coarse_projected(:, j))
762 base_input(:, j) = complement_input(:, j) - &
763 matmul(preconditioner_env%lattice_state_local_operator(:, :, state), &
768 imaginary_residual = 0.0_dp
769 IF (
SIZE(local_input, 2) > 0)
THEN
771 preconditioner_env%lattice_dims, &
772 base_input, local_output, used_fft, imaginary_residual, &
773 preconditioner_env%lattice_rhs_distribution%global_columns)
775 IF (
ALLOCATED(preconditioner_env%lattice_state_local_indices))
THEN
776 ALLOCATE (coarse_residual(
SIZE(coarse_rhs, 1),
SIZE(coarse_rhs, 2)))
777 DO j = 1,
SIZE(local_input, 2)
778 state = preconditioner_env%lattice_rhs_distribution%global_columns(j)
779 coarse_projected(:, j) = &
780 matmul(transpose(preconditioner_env%lattice_state_local_operator(:, :, state)), &
782 coarse_residual(:, j) = matmul( &
783 preconditioner_env%lattice_state_local_coarse_inverse(:, :, state), &
784 coarse_projected(:, j))
785 local_output(preconditioner_env%lattice_state_local_indices(:, state), j) = &
786 local_output(preconditioner_env%lattice_state_local_indices(:, state), j) + &
787 coarse_rhs(:, j) - coarse_residual(:, j)
789 DEALLOCATE (coarse_projected, coarse_residual, coarse_rhs)
791 fft_ok = merge(1, 0, used_fft)
793 IF (
SIZE(local_output) > 0) output_max = maxval(abs(local_output))
794 CALL preconditioner_env%para_env%min(fft_ok)
795 CALL preconditioner_env%para_env%max(imaginary_residual)
796 CALL preconditioner_env%para_env%max(output_max)
797 IF (fft_ok == 0)
THEN
798 cpabort(
"State-dependent lattice preconditioner inverse failed to use FFTs")
800 IF (imaginary_residual > 1.0e-10_dp*max(1.0_dp, output_max))
THEN
801 cpabort(
"State-dependent lattice preconditioner produced a non-real Gamma-point result")
803 occupied_component(:, :) = matmul(transpose(preconditioner_env%lattice_occ_dual), &
805 occupied_update(:, :) = matmul(preconditioner_env%lattice_occ_vectors, occupied_component)
806 local_output(:, :) = local_output - occupied_update
807 occupied_component(:, :) = matmul(transpose(preconditioner_env%lattice_occ_vectors), &
809 DO j = 1,
SIZE(local_input, 2)
810 global_column = preconditioner_env%lattice_rhs_distribution%global_columns(j)
812 occupied_component(i, j) = occupied_component(i, j)/max( &
813 preconditioner_env%energy_gap, &
814 preconditioner_env%full_evals(i) - &
815 preconditioner_env%occ_evals(global_column))
818 occupied_update(:, :) = matmul(preconditioner_env%lattice_occ_vectors, occupied_component)
819 local_output(:, :) = local_output + occupied_update
820 CALL collect_lattice_rhs(preconditioner_env, preconditioner_env%lattice_rhs_distribution, &
821 local_output, matrix_out)
822 DEALLOCATE (base_input, complement_input, local_input, local_output, occupied_component, occupied_update)
823 CALL timestop(handle)
825 END SUBROUTINE apply_lattice_state_operator_fm
834 SUBROUTINE distribute_lattice_rhs(preconditioner_env, matrix_in, distribution, local_input)
839 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :), &
840 INTENT(OUT) :: local_input
842 INTEGER :: destination, i, ientry, j, k, n, &
843 ncol_local, nowned, nrow_local, &
845 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: cursor, send_global_columns, &
847 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
849 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: recv_values, send_values
850 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
851 POINTER :: input_data
853 num_pe = preconditioner_env%para_env%num_pe
855 nrow_local=nrow_local, ncol_local=ncol_local, &
856 row_indices=row_indices, col_indices=col_indices, local_data=input_data)
857 rebuild = distribution%nrow_global /= n .OR. distribution%ncol_global /= k .OR. &
858 distribution%nrow_local /= nrow_local .OR. distribution%ncol_local /= ncol_local .OR. &
859 distribution%num_pe /= num_pe
860 IF (.NOT. rebuild)
THEN
861 rebuild = .NOT.
ALLOCATED(distribution%local_rows) .OR. &
862 .NOT.
ALLOCATED(distribution%local_columns)
864 IF (.NOT. rebuild)
THEN
865 rebuild = any(distribution%local_rows /= row_indices) .OR. &
866 any(distribution%local_columns /= col_indices)
870 distribution%nrow_global = n
871 distribution%ncol_global = k
872 distribution%nrow_local = nrow_local
873 distribution%ncol_local = ncol_local
874 distribution%num_pe = num_pe
875 ALLOCATE (distribution%local_rows(nrow_local), distribution%local_columns(ncol_local))
876 distribution%local_rows(:) = row_indices
877 distribution%local_columns(:) = col_indices
878 ALLOCATE (distribution%send_counts(num_pe), distribution%send_displacements(num_pe), &
879 distribution%recv_counts(num_pe), distribution%recv_displacements(num_pe), &
881 distribution%send_counts = 0
883 destination =
modulo(col_indices(j) - 1, num_pe) + 1
884 distribution%send_counts(destination) = &
885 distribution%send_counts(destination) + nrow_local
887 CALL preconditioner_env%para_env%alltoall(distribution%send_counts, &
888 distribution%recv_counts, 1)
889 distribution%send_displacements(1) = 0
890 distribution%recv_displacements(1) = 0
892 distribution%send_displacements(i) = distribution%send_displacements(i - 1) + &
893 distribution%send_counts(i - 1)
894 distribution%recv_displacements(i) = distribution%recv_displacements(i - 1) + &
895 distribution%recv_counts(i - 1)
898 ALLOCATE (send_global_rows(sum(distribution%send_counts)), &
899 send_global_columns(sum(distribution%send_counts)), &
900 distribution%send_local_rows(sum(distribution%send_counts)), &
901 distribution%send_local_columns(sum(distribution%send_counts)), &
902 distribution%recv_global_rows(sum(distribution%recv_counts)), &
903 distribution%recv_global_columns(sum(distribution%recv_counts)))
904 cursor(:) = distribution%send_displacements
906 destination =
modulo(col_indices(j) - 1, num_pe) + 1
908 cursor(destination) = cursor(destination) + 1
909 ientry = cursor(destination)
910 send_global_rows(ientry) = row_indices(i)
911 send_global_columns(ientry) = col_indices(j)
912 distribution%send_local_rows(ientry) = i
913 distribution%send_local_columns(ientry) = j
916 CALL preconditioner_env%para_env%alltoall( &
917 send_global_rows, distribution%send_counts, distribution%send_displacements, &
918 distribution%recv_global_rows, distribution%recv_counts, distribution%recv_displacements)
919 CALL preconditioner_env%para_env%alltoall( &
920 send_global_columns, distribution%send_counts, distribution%send_displacements, &
921 distribution%recv_global_columns, distribution%recv_counts, distribution%recv_displacements)
924 DO j = preconditioner_env%para_env%mepos + 1, k, num_pe
927 ALLOCATE (distribution%global_columns(nowned))
929 DO j = preconditioner_env%para_env%mepos + 1, k, num_pe
931 distribution%global_columns(nowned) = j
933 DEALLOCATE (cursor, send_global_columns, send_global_rows)
936 nowned =
SIZE(distribution%global_columns)
937 ALLOCATE (local_input(n, nowned), source=0.0_dp)
938 ALLOCATE (send_values(sum(distribution%send_counts)), &
939 recv_values(sum(distribution%recv_counts)))
940 DO ientry = 1,
SIZE(send_values)
941 send_values(ientry) = input_data(distribution%send_local_rows(ientry), &
942 distribution%send_local_columns(ientry))
944 CALL preconditioner_env%para_env%alltoall( &
945 send_values, distribution%send_counts, distribution%send_displacements, &
946 recv_values, distribution%recv_counts, distribution%recv_displacements)
947 DO ientry = 1,
SIZE(recv_values)
948 slot = (distribution%recv_global_columns(ientry) - 1)/num_pe + 1
949 local_input(distribution%recv_global_rows(ientry), slot) = recv_values(ientry)
952 DEALLOCATE (recv_values, send_values)
954 END SUBROUTINE distribute_lattice_rhs
964 SUBROUTINE collect_lattice_rhs(preconditioner_env, distribution, local_output, matrix_out, scale_factor)
968 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: local_output
970 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: scale_factor
972 INTEGER :: ientry, num_pe, slot
973 REAL(kind=
dp) :: scale
974 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: recv_values, send_values
975 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
976 POINTER :: output_data
978 num_pe = preconditioner_env%para_env%num_pe
979 cpassert(
SIZE(local_output, 1) == distribution%nrow_global)
980 cpassert(
SIZE(local_output, 2) ==
SIZE(distribution%global_columns))
982 IF (
PRESENT(scale_factor)) scale = scale_factor
983 ALLOCATE (send_values(sum(distribution%recv_counts)), &
984 recv_values(sum(distribution%send_counts)))
985 DO ientry = 1,
SIZE(send_values)
986 slot = (distribution%recv_global_columns(ientry) - 1)/num_pe + 1
987 send_values(ientry) = local_output(distribution%recv_global_rows(ientry), slot)
989 CALL preconditioner_env%para_env%alltoall( &
990 send_values, distribution%recv_counts, distribution%recv_displacements, &
991 recv_values, distribution%send_counts, distribution%send_displacements)
995 DO ientry = 1,
SIZE(recv_values)
996 output_data(distribution%send_local_rows(ientry), &
997 distribution%send_local_columns(ientry)) = scale*recv_values(ientry)
999 DEALLOCATE (recv_values, send_values)
1001 END SUBROUTINE collect_lattice_rhs
1009 SUBROUTINE apply_lattice_operator_dbcsr(preconditioner_env, matrix_in, matrix_out)
1019 CALL dbcsr_get_info(matrix_in, nfullrows_total=n, nfullcols_total=k)
1021 context=preconditioner_env%ctxt, &
1022 para_env=preconditioner_env%para_env)
1023 CALL cp_fm_create(input_fm, fm_struct, name=
"lattice preconditioner input")
1024 CALL cp_fm_create(output_fm, fm_struct, name=
"lattice preconditioner output")
1027 CALL apply_lattice_operator_fm(preconditioner_env, input_fm, output_fm)
1032 END SUBROUTINE apply_lattice_operator_dbcsr
1040 SUBROUTINE apply_low_rank_dbcsr(preconditioner_env, matrix_in, matrix_out)
1045 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_low_rank_dbcsr'
1047 INTEGER :: col, col_offset, col_size, handle, i, j, &
1048 k, n, nocc, rank_used, row, &
1049 row_offset, row_size
1050 REAL(kind=
dp) :: correction
1051 REAL(kind=
dp),
DIMENSION(:, :),
POINTER ::
DATA
1055 CALL timeset(routinen, handle)
1058 CALL apply_low_rank_dbcsr_via_fm(preconditioner_env, matrix_in, matrix_out)
1059 CALL timestop(handle)
1063 cpassert(
ASSOCIATED(preconditioner_env%base_dbcsr_matrix))
1064 cpassert(
ASSOCIATED(preconditioner_env%dbcsr_matrix))
1065 cpassert(
ASSOCIATED(preconditioner_env%full_evals))
1066 cpassert(
ASSOCIATED(preconditioner_env%occ_evals))
1068 CALL dbcsr_get_info(matrix_in, nfullrows_total=n, nfullcols_total=k)
1069 nocc =
SIZE(preconditioner_env%occ_evals)
1070 cpassert(n ==
SIZE(preconditioner_env%full_evals))
1071 rank_used = min(preconditioner_env%spectral_rank, n - nocc)
1074 CALL dbcsr_multiply(
'N',
'N', preconditioner_env%spectral_base_scale, &
1075 preconditioner_env%base_dbcsr_matrix, matrix_in, 0.0_dp, matrix_out)
1077 IF (rank_used > 0)
THEN
1078 CALL dbcsr_copy(matrix_tmp, matrix_in, name=routinen)
1080 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, preconditioner_env%dbcsr_matrix, &
1081 matrix_in, 0.0_dp, matrix_tmp, &
1082 first_row=nocc + 1, last_row=nocc + rank_used)
1087 row_size=row_size, col_size=col_size, &
1088 row_offset=row_offset, col_offset=col_offset)
1091 IF (row_offset + i - 1 >= nocc + 1 .AND. &
1092 row_offset + i - 1 <= nocc + rank_used)
THEN
1094 preconditioner_env%full_evals(row_offset + i - 1), &
1095 preconditioner_env%spectral_reference, &
1096 preconditioner_env%energy_gap) &
1097 - preconditioner_env%spectral_base_scale
1098 DATA(i, j) =
DATA(i, j)*correction
1105 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, preconditioner_env%dbcsr_matrix, &
1106 matrix_tmp, 1.0_dp, matrix_out, &
1107 first_k=nocc + 1, last_k=nocc + rank_used)
1111 CALL timestop(handle)
1113 END SUBROUTINE apply_low_rank_dbcsr
1121 SUBROUTINE apply_low_rank_dbcsr_via_fm(preconditioner_env, matrix_in, matrix_out)
1131 CALL dbcsr_get_info(matrix_in, nfullrows_total=n, nfullcols_total=k)
1133 context=preconditioner_env%ctxt, &
1134 para_env=preconditioner_env%para_env)
1135 CALL cp_fm_create(input_fm, fm_struct, name=
"lattice low-rank input")
1136 CALL cp_fm_create(output_fm, fm_struct, name=
"lattice low-rank output")
1139 CALL apply_low_rank_fm(preconditioner_env, input_fm, output_fm)
1144 END SUBROUTINE apply_low_rank_dbcsr_via_fm
1152 SUBROUTINE apply_full_all(preconditioner_env, matrix_in, matrix_out)
1155 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_in, matrix_out
1157 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_full_all'
1159 INTEGER :: handle, i, j, k, n, ncol_local, &
1161 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
1162 REAL(kind=
dp) :: dum
1163 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
1164 POINTER :: local_data
1167 CALL timeset(routinen, handle)
1171 CALL cp_fm_create(matrix_tmp, matrix_in%matrix_struct, name=
"apply_full_all")
1172 CALL cp_fm_get_info(matrix_tmp, nrow_local=nrow_local, ncol_local=ncol_local, &
1173 row_indices=row_indices, col_indices=col_indices, local_data=local_data)
1176 CALL parallel_gemm(
'T',
'N', n, k, n, 1.0_dp, preconditioner_env%fm, &
1177 matrix_in, 0.0_dp, matrix_tmp)
1180 DO j = 1, ncol_local
1181 DO i = 1, nrow_local
1182 dum = 1.0_dp/max(preconditioner_env%energy_gap, &
1183 preconditioner_env%full_evals(row_indices(i)) - preconditioner_env%occ_evals(col_indices(j)))
1184 local_data(i, j) = local_data(i, j)*dum
1189 CALL parallel_gemm(
'N',
'N', n, k, n, 1.0_dp, preconditioner_env%fm, &
1190 matrix_tmp, 0.0_dp, matrix_out)
1194 CALL timestop(handle)
1196 END SUBROUTINE apply_full_all
1204 SUBROUTINE apply_all(preconditioner_env, matrix_in, matrix_out)
1209 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_all'
1211 INTEGER :: col, col_offset, col_size, handle, i, j, &
1212 row, row_offset, row_size
1213 REAL(kind=
dp) :: dum
1214 REAL(kind=
dp),
DIMENSION(:, :),
POINTER ::
DATA
1218 CALL timeset(routinen, handle)
1220 CALL dbcsr_copy(matrix_tmp, matrix_in, name=
"apply_full_all")
1221 CALL dbcsr_multiply(
'T',
'N', 1.0_dp, preconditioner_env%dbcsr_matrix, &
1222 matrix_in, 0.0_dp, matrix_tmp)
1227 row_size=row_size, col_size=col_size, &
1228 row_offset=row_offset, col_offset=col_offset)
1231 dum = 1.0_dp/max(preconditioner_env%energy_gap, &
1232 preconditioner_env%full_evals(row_offset + i - 1) &
1233 - preconditioner_env%occ_evals(col_offset + j - 1))
1234 DATA(i, j) =
DATA(i, j)*dum
1241 CALL dbcsr_multiply(
'N',
'N', 1.0_dp, preconditioner_env%dbcsr_matrix, &
1242 matrix_tmp, 0.0_dp, matrix_out)
1244 CALL timestop(handle)
1246 END SUBROUTINE apply_all
1254 SUBROUTINE apply_full_all_covariant(preconditioner_env, matrix_in, matrix_out)
1257 TYPE(
cp_fm_type),
INTENT(IN) :: matrix_in, matrix_out
1259 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_full_all_covariant'
1261 INTEGER :: handle, k, n
1262 TYPE(
cp_fm_type) :: canonical_in, canonical_out
1264 CALL timeset(routinen, handle)
1265 cpassert(
ASSOCIATED(preconditioner_env%occ_rotation))
1268 CALL cp_fm_create(canonical_in, matrix_in%matrix_struct, name=routinen)
1269 CALL cp_fm_create(canonical_out, matrix_out%matrix_struct, name=routinen)
1271 preconditioner_env%occ_rotation, 0.0_dp, canonical_in)
1272 IF (preconditioner_env%lattice_fft_active)
THEN
1273 CALL apply_lattice_state_operator_fm(preconditioner_env, canonical_in, canonical_out)
1275 CALL apply_full_all(preconditioner_env, canonical_in, canonical_out)
1277 CALL parallel_gemm(
'N',
'T', n, k, k, 1.0_dp, canonical_out, &
1278 preconditioner_env%occ_rotation, 0.0_dp, matrix_out)
1281 CALL timestop(handle)
1283 END SUBROUTINE apply_full_all_covariant
1291 SUBROUTINE apply_all_covariant(preconditioner_env, matrix_in, matrix_out)
1296 CHARACTER(len=*),
PARAMETER :: routinen =
'apply_all_covariant'
1298 INTEGER :: handle, k, n
1301 TYPE(
dbcsr_type) :: canonical_in, canonical_out
1303 CALL timeset(routinen, handle)
1304 cpassert(
ASSOCIATED(preconditioner_env%occ_rotation))
1305 CALL dbcsr_get_info(matrix_in, nfullrows_total=n, nfullcols_total=k)
1307 IF (preconditioner_env%lattice_fft_active)
THEN
1310 context=preconditioner_env%ctxt, &
1311 para_env=preconditioner_env%para_env)
1316 CALL apply_full_all_covariant(preconditioner_env, input_fm, output_fm)
1320 CALL timestop(handle)
1324 IF (.NOT.
ASSOCIATED(preconditioner_env%occ_rotation_dbcsr))
THEN
1325 CALL dbcsr_init_p(preconditioner_env%occ_rotation_dbcsr)
1327 template=matrix_in, m=k, n=k, &
1328 sym=dbcsr_type_no_symmetry)
1330 preconditioner_env%occ_rotation_dbcsr)
1333 CALL dbcsr_copy(canonical_in, matrix_in, name=routinen)
1335 CALL dbcsr_copy(canonical_out, matrix_out, name=routinen)
1338 preconditioner_env%occ_rotation_dbcsr, 0.0_dp, canonical_in)
1339 CALL apply_all(preconditioner_env, canonical_in, canonical_out)
1341 preconditioner_env%occ_rotation_dbcsr, 0.0_dp, matrix_out)
1344 CALL timestop(handle)
1346 END SUBROUTINE apply_all_covariant
static GRID_HOST_DEVICE int modulo(int a, int m)
Equivalent of Fortran's MODULO, which always return a positive number. https://gcc....
Basic linear algebra operations for complex full matrices.
subroutine, public cp_cfm_gemm(transa, transb, m, n, k, alpha, matrix_a, matrix_b, beta, matrix_c, a_first_col, a_first_row, b_first_col, b_first_row, c_first_col, c_first_row)
Performs one of the matrix-matrix operations: matrix_c = alpha * op1( matrix_a ) * op2( matrix_b ) + ...
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.
subroutine, public cp_cfm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, matrix_struct, para_env)
Returns information about a full matrix.
subroutine, public cp_cfm_to_fm(msource, mtargetr, mtargeti)
Copy real and imaginary parts of a complex full matrix into separate real-value full matrices.
logical function, public dbcsr_iterator_blocks_left(iterator)
...
subroutine, public dbcsr_iterator_stop(iterator)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_multiply(transa, transb, alpha, matrix_a, matrix_b, beta, matrix_c, first_row, last_row, first_column, last_column, first_k, last_k, retain_sparsity, filter_eps, flop)
...
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)
...
subroutine, public dbcsr_init_p(matrix)
...
subroutine, public dbcsr_iterator_next_block(iterator, row, column, block, block_number_argument_has_been_removed, row_size, col_size, row_offset, col_offset, transposed)
...
subroutine, public dbcsr_iterator_start(iterator, matrix, shared, dynamic, dynamic_byrows)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
DBCSR operations in CP2K.
subroutine, public copy_dbcsr_to_fm(matrix, fm)
Copy a DBCSR matrix to a BLACS matrix.
subroutine, public cp_dbcsr_m_by_n_from_template(matrix, template, m, n, sym)
Utility function to create an arbitrary shaped dbcsr matrix with the same processor grid as the templ...
subroutine, public copy_fm_to_dbcsr(fm, matrix, keep_sparsity)
Copy a BLACS matrix to a dbcsr matrix.
Basic linear algebra operations for full matrices.
subroutine, public cp_fm_scale_and_add(alpha, matrix_a, beta, matrix_b)
calc A <- alpha*A + beta*B optimized for alpha == 1.0 (just add beta*B) and beta == 0....
subroutine, public cp_fm_scale(alpha, matrix_a)
scales a matrix matrix_a = alpha * matrix_b
various cholesky decomposition related routines
subroutine, public cp_fm_cholesky_restore(fm_matrix, neig, fm_matrixb, fm_matrixout, op, pos, transa)
apply Cholesky decomposition op can be "SOLVE" (out = U^-1 * in) or "MULTIPLY" (out = U * in) pos can...
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_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
creates a new full matrix with the given structure
Defines the basic variable types.
integer, parameter, public dp
Block-circulant inverse operators for replicated-cell OT preconditioners.
subroutine, public apply_lattice_inverse_dense(inverse_k, lattice_dims, matrix_in, matrix_out, used_fft, imaginary_residual)
Apply inverse Fourier blocks to a dense cell-major real matrix.
subroutine, public apply_lattice_state_inverse_dense(inverse_k, lattice_dims, matrix_in, matrix_out, used_fft, imaginary_residual, state_indices)
Apply one inverse Fourier operator to every column of a dense real matrix.
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.
Definition of mathematical constants and functions.
complex(kind=dp), parameter, public z_one
real(kind=dp), parameter, public degree
complex(kind=dp), parameter, public z_zero
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)
...
subroutine, public release_lattice_rhs_distribution(distribution)
Release a cached lattice right-hand-side communication map.
Represent a complex full matrix.
keeps the information about the structure of a full matrix