(git:691081d)
Loading...
Searching...
No Matches
gw_fm_utils.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Common full-matrix operations used by GW modules.
10!> \par History
11!> 09.2026 created Jan Wilhelm
12! **************************************************************************************************
14 USE cp_cfm_types, ONLY: cp_cfm_create,&
21 USE cp_fm_diag, ONLY: cp_fm_power
22 USE cp_fm_types, ONLY: cp_fm_create,&
27 USE kinds, ONLY: dp
28 USE mathconstants, ONLY: z_one,&
29 z_zero
31#include "./base/base_uses.f90"
32
33 IMPLICIT NONE
34 PRIVATE
35
36 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'gw_fm_utils'
37
39
41 MODULE PROCEDURE fm_contract_aba, fm_contract_aba_set
42 END INTERFACE fm_contract_aba
43
44CONTAINS
45
46! **************************************************************************************************
47!> \brief Computes A^H B A for complex full matrices.
48!> \param matrix_A left and right matrix A; H denotes its Hermitian transpose
49!> \param matrix_B input matrix B; overwritten by A^H B A if matrix_C is absent
50!> \param matrix_C optional output matrix C=A^H B A
51! **************************************************************************************************
52 SUBROUTINE cfm_contract_aba(matrix_A, matrix_B, matrix_C)
53 TYPE(cp_cfm_type), INTENT(IN) :: matrix_a
54 TYPE(cp_cfm_type), INTENT(INOUT) :: matrix_b
55 TYPE(cp_cfm_type), INTENT(INOUT), OPTIONAL :: matrix_c
56
57 INTEGER :: ncol, nrow
58 TYPE(cp_cfm_type) :: work
59
60 cpassert(ASSOCIATED(matrix_a%matrix_struct))
61 cpassert(ASSOCIATED(matrix_b%matrix_struct))
62 CALL cp_cfm_get_info(matrix_a, nrow_global=nrow, ncol_global=ncol)
63 cpassert(nrow == ncol)
64 CALL cp_cfm_create(work, matrix_a%matrix_struct)
65
66 CALL parallel_gemm("N", "N", nrow, nrow, nrow, z_one, matrix_b, matrix_a, &
67 z_zero, work)
68 IF (PRESENT(matrix_c)) THEN
69 cpassert(ASSOCIATED(matrix_c%matrix_struct))
70 CALL parallel_gemm("C", "N", nrow, nrow, nrow, z_one, matrix_a, work, &
71 z_zero, matrix_c)
72 ELSE
73 CALL parallel_gemm("C", "N", nrow, nrow, nrow, z_one, matrix_a, work, &
74 z_zero, matrix_b)
75 END IF
76
77 CALL cp_cfm_release(work)
78
79 END SUBROUTINE cfm_contract_aba
80
81! **************************************************************************************************
82!> \brief Inverts a symmetric matrix. First, Cholesky decomposition is tried.
83!> If it fails, the matrix is diagonalized and inverted by taking
84!> inverse eigenvalues.
85!> \param matrix_A input A; output inverse or filtered pseudoinverse
86!> \param eigenvalue_threshold optional relative eigenvalue threshold
87!> \param unit_nr optional output unit for a failed Cholesky decomposition
88! **************************************************************************************************
89 SUBROUTINE fm_invert(matrix_A, eigenvalue_threshold, unit_nr)
90 TYPE(cp_fm_type), INTENT(INOUT) :: matrix_a
91 REAL(kind=dp), INTENT(IN), OPTIONAL :: eigenvalue_threshold
92 INTEGER, INTENT(IN), OPTIONAL :: unit_nr
93
94 INTEGER :: info, n_dependent
95 LOGICAL :: cholesky_successful
96 REAL(kind=dp) :: threshold
97 TYPE(cp_fm_type) :: work
98
99 threshold = 0.0_dp
100 IF (PRESENT(eigenvalue_threshold)) threshold = eigenvalue_threshold
101 CALL cp_fm_create(work, matrix_a%matrix_struct)
102
103 ! Preserve A because a failed Cholesky decomposition overwrites it.
104 CALL cp_fm_to_fm(matrix_a, work)
105 CALL cp_fm_cholesky_decompose(matrix_a, info_out=info)
106 cholesky_successful = info == 0
107 n_dependent = 0
108 IF (cholesky_successful) THEN
109 CALL cp_fm_cholesky_invert(matrix_a)
110 CALL cp_fm_uplo_to_full(matrix_a, work)
111 ELSE
112 CALL cp_fm_to_fm(work, matrix_a)
113 CALL cp_fm_power(matrix_a, work, -1.0_dp, threshold, n_dependent)
114 IF (PRESENT(unit_nr)) THEN
115 IF (unit_nr > 0) THEN
116 WRITE (unit_nr, '(T2,A)') &
117 'Cholesky decomposition failed; matrix inverted by diagonalization.'
118 WRITE (unit_nr, '(T2,A,T72,I9)') 'Discarded eigenmodes:', n_dependent
119 END IF
120 END IF
121 END IF
122 CALL cp_fm_release(work)
123
124 END SUBROUTINE fm_invert
125
126! **************************************************************************************************
127!> \brief For input A, computes B such that B^T B=A.
128!> First, Cholesky decomposition is tried. If it fails, B is computed
129!> by diagonalizing A.
130!> \param matrix_A symmetric input matrix A, retained unchanged
131!> \param matrix_B output matrix B
132!> \param eigenvalue_threshold optional relative eigenvalue threshold
133!> \param unit_nr optional output unit for a failed Cholesky decomposition
134! **************************************************************************************************
135 SUBROUTINE fm_sqrt(matrix_A, matrix_B, eigenvalue_threshold, unit_nr)
136 TYPE(cp_fm_type), INTENT(IN) :: matrix_a
137 TYPE(cp_fm_type), INTENT(INOUT) :: matrix_b
138 REAL(kind=dp), INTENT(IN), OPTIONAL :: eigenvalue_threshold
139 INTEGER, INTENT(IN), OPTIONAL :: unit_nr
140
141 INTEGER :: i_row, info, j_col, n_dependent, &
142 ncol_local, nrow_local
143 INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
144 LOGICAL :: cholesky_successful
145 REAL(kind=dp) :: threshold
146 TYPE(cp_fm_type) :: work
147
148 threshold = 0.0_dp
149 IF (PRESENT(eigenvalue_threshold)) threshold = eigenvalue_threshold
150 CALL cp_fm_create(work, matrix_a%matrix_struct)
151
152 CALL cp_fm_to_fm(matrix_a, matrix_b)
153 CALL cp_fm_cholesky_decompose(matrix_b, info_out=info)
154 cholesky_successful = info == 0
155 IF (cholesky_successful) THEN
156 n_dependent = 0
157 CALL cp_fm_get_info(matrix=matrix_b, nrow_local=nrow_local, ncol_local=ncol_local, &
158 row_indices=row_indices, col_indices=col_indices)
159 DO j_col = 1, ncol_local
160 DO i_row = 1, nrow_local
161 IF (row_indices(i_row) > col_indices(j_col)) THEN
162 matrix_b%local_data(i_row, j_col) = 0.0_dp
163 END IF
164 END DO
165 END DO
166 ELSE
167 CALL cp_fm_to_fm(matrix_a, matrix_b)
168 CALL cp_fm_power(matrix_b, work, 0.5_dp, threshold, n_dependent)
169 IF (PRESENT(unit_nr)) THEN
170 IF (unit_nr > 0) THEN
171 WRITE (unit_nr, '(T2,A)') &
172 'Cholesky decomposition failed, using diagonalization.'
173 WRITE (unit_nr, '(T2,A,T72,I9)') 'Discarded eigenmodes:', n_dependent
174 END IF
175 END IF
176 END IF
177 CALL cp_fm_release(work)
178
179 END SUBROUTINE fm_sqrt
180
181! **************************************************************************************************
182!> \brief Computes A^T B A.
183!> \param matrix_A left and right matrix A
184!> \param matrix_B input matrix B; overwritten by A^T B A if matrix_C is absent
185!> \param matrix_C optional output matrix C=A^T B A
186! **************************************************************************************************
187 SUBROUTINE fm_contract_aba(matrix_A, matrix_B, matrix_C)
188 TYPE(cp_fm_type), INTENT(IN) :: matrix_A
189 TYPE(cp_fm_type), INTENT(INOUT) :: matrix_B
190 TYPE(cp_fm_type), INTENT(INOUT), OPTIONAL :: matrix_C
191
192 INTEGER :: ncol, nrow
193 TYPE(cp_fm_type) :: work
194
195 cpassert(ASSOCIATED(matrix_a%matrix_struct))
196 cpassert(ASSOCIATED(matrix_b%matrix_struct))
197 CALL cp_fm_get_info(matrix_a, nrow_global=nrow, ncol_global=ncol)
198 cpassert(nrow == ncol)
199 CALL cp_fm_create(work, matrix_a%matrix_struct)
200
201 CALL parallel_gemm("N", "N", nrow, nrow, nrow, 1.0_dp, matrix_b, matrix_a, &
202 0.0_dp, work)
203 IF (PRESENT(matrix_c)) THEN
204 cpassert(ASSOCIATED(matrix_c%matrix_struct))
205 CALL parallel_gemm("T", "N", nrow, nrow, nrow, 1.0_dp, matrix_a, work, &
206 0.0_dp, matrix_c)
207 ELSE
208 CALL parallel_gemm("T", "N", nrow, nrow, nrow, 1.0_dp, matrix_a, work, &
209 0.0_dp, matrix_b)
210 END IF
211
212 CALL cp_fm_release(work)
213
214 END SUBROUTINE fm_contract_aba
215
216! **************************************************************************************************
217!> \brief Computes A^T B_i A for a set of matrices.
218!> \param matrix_A left and right matrix A
219!> \param matrix_B input matrices B_i; overwritten if matrix_C is absent
220!> \param matrix_C optional output matrices C_i=A^T B_i A
221! **************************************************************************************************
222 SUBROUTINE fm_contract_aba_set(matrix_A, matrix_B, matrix_C)
223 TYPE(cp_fm_type), INTENT(IN) :: matrix_A
224 TYPE(cp_fm_type), DIMENSION(:), INTENT(INOUT) :: matrix_B
225 TYPE(cp_fm_type), DIMENSION(:), INTENT(INOUT), &
226 OPTIONAL :: matrix_C
227
228 INTEGER :: i, ncol, nrow
229 TYPE(cp_fm_type) :: work
230
231 cpassert(ASSOCIATED(matrix_a%matrix_struct))
232 CALL cp_fm_get_info(matrix_a, nrow_global=nrow, ncol_global=ncol)
233 cpassert(nrow == ncol)
234 IF (PRESENT(matrix_c)) THEN
235 cpassert(SIZE(matrix_c) == SIZE(matrix_b))
236 END IF
237 CALL cp_fm_create(work, matrix_a%matrix_struct)
238
239 DO i = 1, SIZE(matrix_b)
240 cpassert(ASSOCIATED(matrix_b(i)%matrix_struct))
241 CALL parallel_gemm("N", "N", nrow, nrow, nrow, 1.0_dp, matrix_b(i), matrix_a, &
242 0.0_dp, work)
243 IF (PRESENT(matrix_c)) THEN
244 cpassert(ASSOCIATED(matrix_c(i)%matrix_struct))
245 CALL parallel_gemm("T", "N", nrow, nrow, nrow, 1.0_dp, matrix_a, work, &
246 0.0_dp, matrix_c(i))
247 ELSE
248 CALL parallel_gemm("T", "N", nrow, nrow, nrow, 1.0_dp, matrix_a, work, &
249 0.0_dp, matrix_b(i))
250 END IF
251 END DO
252
253 CALL cp_fm_release(work)
254
255 END SUBROUTINE fm_contract_aba_set
256
257END MODULE gw_fm_utils
Represents a complex full matrix distributed on many processors.
subroutine, public cp_cfm_release(matrix)
Releases a full matrix.
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.
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)
used to replace the cholesky decomposition by the inverse
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...
Definition cp_fm_diag.F:17
subroutine, public cp_fm_power(matrix, work, exponent, threshold, n_dependent, verbose, eigvals)
...
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
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
Common full-matrix operations used by GW modules.
Definition gw_fm_utils.F:13
subroutine, public cfm_contract_aba(matrix_a, matrix_b, matrix_c)
Computes A^H B A for complex full matrices.
Definition gw_fm_utils.F:53
subroutine, public fm_sqrt(matrix_a, matrix_b, eigenvalue_threshold, unit_nr)
For input A, computes B such that B^T B=A. First, Cholesky decomposition is tried....
subroutine, public fm_invert(matrix_a, eigenvalue_threshold, unit_nr)
Inverts a symmetric matrix. First, Cholesky decomposition is tried. If it fails, the matrix is diagon...
Definition gw_fm_utils.F:90
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Definition of mathematical constants and functions.
complex(kind=dp), parameter, public z_one
complex(kind=dp), parameter, public z_zero
basic linear algebra operations for full matrixes
Represent a complex full matrix.
represent a full matrix