(git:34ef472)
preconditioner_apply.F
Go to the documentation of this file.
1 !--------------------------------------------------------------------------------------------------!
2 ! CP2K: A general program to perform molecular dynamics simulations !
3 ! Copyright 2000-2024 CP2K developers group <https://cp2k.org> !
4 ! !
5 ! SPDX-License-Identifier: GPL-2.0-or-later !
6 !--------------------------------------------------------------------------------------------------!
7 
8 ! **************************************************************************************************
9 !> \brief computes preconditioners, and implements methods to apply them
10 !> currently used in qs_ot
11 !> \par History
12 !> - [UB] 2009-05-13 Adding stable approximate inverse (full and sparse)
13 !> \author Joost VandeVondele (09.2002)
14 ! **************************************************************************************************
17  USE cp_fm_types, ONLY: cp_fm_create,&
19  cp_fm_release,&
20  cp_fm_type
21  USE dbcsr_api, ONLY: &
22  dbcsr_copy, dbcsr_iterator_blocks_left, dbcsr_iterator_next_block, dbcsr_iterator_start, &
23  dbcsr_iterator_stop, dbcsr_iterator_type, dbcsr_multiply, dbcsr_release, dbcsr_type
32  USE kinds, ONLY: dp
33  USE parallel_gemm_api, ONLY: parallel_gemm
34  USE preconditioner_types, ONLY: preconditioner_type
35 #include "./base/base_uses.f90"
36 
37  IMPLICIT NONE
38  PRIVATE
39 
40  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'preconditioner_apply'
41 
43 
44 CONTAINS
45 
46 ! **************************************************************************************************
47 !> \brief applies a previously created preconditioner to a full matrix
48 !> \param preconditioner_env ...
49 !> \param matrix_in ...
50 !> \param matrix_out ...
51 ! **************************************************************************************************
52  SUBROUTINE apply_preconditioner_fm(preconditioner_env, matrix_in, matrix_out)
53 
54  TYPE(preconditioner_type) :: preconditioner_env
55  TYPE(cp_fm_type), INTENT(IN) :: matrix_in, matrix_out
56 
57  CHARACTER(len=*), PARAMETER :: routinen = 'apply_preconditioner_fm'
58 
59  INTEGER :: handle
60 
61  CALL timeset(routinen, handle)
62 
63  SELECT CASE (preconditioner_env%in_use)
64  CASE (0)
65  cpabort("No preconditioner in use")
67  CALL apply_full_single(preconditioner_env, matrix_in, matrix_out)
68  CASE (ot_precond_full_all)
69  CALL apply_full_all(preconditioner_env, matrix_in, matrix_out)
71  SELECT CASE (preconditioner_env%solver)
73  CALL apply_full_single(preconditioner_env, matrix_in, matrix_out)
75  CALL apply_full_direct(preconditioner_env, matrix_in, matrix_out)
76  CASE DEFAULT
77  cpabort("Solver not implemented")
78  END SELECT
79  CASE DEFAULT
80  cpabort("Unknown preconditioner")
81  END SELECT
82 
83  CALL timestop(handle)
84 
85  END SUBROUTINE apply_preconditioner_fm
86 
87 ! **************************************************************************************************
88 !> \brief ...
89 !> \param preconditioner_env ...
90 !> \param matrix_in ...
91 !> \param matrix_out ...
92 ! **************************************************************************************************
93  SUBROUTINE apply_preconditioner_dbcsr(preconditioner_env, matrix_in, matrix_out)
94 
95  TYPE(preconditioner_type) :: preconditioner_env
96  TYPE(dbcsr_type) :: matrix_in, matrix_out
97 
98  CHARACTER(len=*), PARAMETER :: routinen = 'apply_preconditioner_dbcsr'
99 
100  INTEGER :: handle
101 
102  CALL timeset(routinen, handle)
103 
104  SELECT CASE (preconditioner_env%in_use)
105  CASE (0)
106  cpabort("No preconditioner in use")
108  CALL apply_single(preconditioner_env, matrix_in, matrix_out)
109  CASE (ot_precond_full_all)
110  CALL apply_all(preconditioner_env, matrix_in, matrix_out)
112  SELECT CASE (preconditioner_env%solver)
114  CALL apply_single(preconditioner_env, matrix_in, matrix_out)
116  cpabort("Apply_full_direct not supported with ot")
117  !CALL apply_full_direct(preconditioner_env, matrix_in, matrix_out)
118  CASE DEFAULT
119  cpabort("Wrong solver")
120  END SELECT
121  CASE DEFAULT
122  cpabort("Wrong preconditioner")
123  END SELECT
124 
125  CALL timestop(handle)
126 
127  END SUBROUTINE apply_preconditioner_dbcsr
128 
129 ! **************************************************************************************************
130 !> \brief apply to full matrix, complete inversion has already been done
131 !> \param preconditioner_env ...
132 !> \param matrix_in ...
133 !> \param matrix_out ...
134 ! **************************************************************************************************
135  SUBROUTINE apply_full_single(preconditioner_env, matrix_in, matrix_out)
136 
137  TYPE(preconditioner_type) :: preconditioner_env
138  TYPE(cp_fm_type), INTENT(IN) :: matrix_in, matrix_out
139 
140  CHARACTER(len=*), PARAMETER :: routinen = 'apply_full_single'
141 
142  INTEGER :: handle, k, n
143 
144  CALL timeset(routinen, handle)
145 
146  CALL cp_fm_get_info(matrix_in, nrow_global=n, ncol_global=k)
147  CALL parallel_gemm('N', 'N', n, k, n, 1.0_dp, preconditioner_env%fm, &
148  matrix_in, 0.0_dp, matrix_out)
149  CALL timestop(handle)
150 
151  END SUBROUTINE apply_full_single
152 
153 ! **************************************************************************************************
154 !> \brief apply to dbcsr matrix, complete inversion has already been done
155 !> \param preconditioner_env ...
156 !> \param matrix_in ...
157 !> \param matrix_out ...
158 ! **************************************************************************************************
159  SUBROUTINE apply_single(preconditioner_env, matrix_in, matrix_out)
160 
161  TYPE(preconditioner_type) :: preconditioner_env
162  TYPE(dbcsr_type) :: matrix_in, matrix_out
163 
164  CHARACTER(len=*), PARAMETER :: routinen = 'apply_single'
165 
166  INTEGER :: handle
167 
168  CALL timeset(routinen, handle)
169 
170  IF (.NOT. ASSOCIATED(preconditioner_env%dbcsr_matrix)) &
171  cpabort("NOT ASSOCIATED preconditioner_env%dbcsr_matrix")
172  CALL dbcsr_multiply('N', 'N', 1.0_dp, preconditioner_env%dbcsr_matrix, matrix_in, &
173  0.0_dp, matrix_out)
174 
175  CALL timestop(handle)
176 
177  END SUBROUTINE apply_single
178 
179 ! **************************************************************************************************
180 !> \brief preconditioner contains the factorization, application done by
181 !> solving the linear system
182 !> \param preconditioner_env ...
183 !> \param matrix_in ...
184 !> \param matrix_out ...
185 ! **************************************************************************************************
186  SUBROUTINE apply_full_direct(preconditioner_env, matrix_in, matrix_out)
187 
188  TYPE(preconditioner_type) :: preconditioner_env
189  TYPE(cp_fm_type), INTENT(IN) :: matrix_in, matrix_out
190 
191  CHARACTER(len=*), PARAMETER :: routinen = 'apply_full_direct'
192 
193  INTEGER :: handle, k, n
194  TYPE(cp_fm_type) :: work
195 
196  CALL timeset(routinen, handle)
197 
198  CALL cp_fm_get_info(matrix_in, nrow_global=n, ncol_global=k)
199  CALL cp_fm_create(work, matrix_in%matrix_struct, name="apply_full_single", &
200  use_sp=matrix_in%use_sp)
201  CALL cp_fm_cholesky_restore(matrix_in, k, preconditioner_env%fm, work,&
202  & "SOLVE", transa="T")
203  CALL cp_fm_cholesky_restore(work, k, preconditioner_env%fm, matrix_out,&
204  & "SOLVE", transa="N")
205  CALL cp_fm_release(work)
206 
207  CALL timestop(handle)
208 
209  END SUBROUTINE apply_full_direct
210 
211 ! **************************************************************************************************
212 !> \brief full all to a full matrix
213 !> \param preconditioner_env ...
214 !> \param matrix_in ...
215 !> \param matrix_out ...
216 ! **************************************************************************************************
217  SUBROUTINE apply_full_all(preconditioner_env, matrix_in, matrix_out)
218 
219  TYPE(preconditioner_type) :: preconditioner_env
220  TYPE(cp_fm_type), INTENT(IN) :: matrix_in, matrix_out
221 
222  CHARACTER(len=*), PARAMETER :: routinen = 'apply_full_all'
223 
224  INTEGER :: handle, i, j, k, n, ncol_local, &
225  nrow_local
226  INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
227  REAL(kind=dp) :: dum
228  REAL(kind=dp), CONTIGUOUS, DIMENSION(:, :), &
229  POINTER :: local_data
230  TYPE(cp_fm_type) :: matrix_tmp
231 
232  CALL timeset(routinen, handle)
233 
234  CALL cp_fm_get_info(matrix_in, nrow_global=n, ncol_global=k)
235 
236  CALL cp_fm_create(matrix_tmp, matrix_in%matrix_struct, name="apply_full_all")
237  CALL cp_fm_get_info(matrix_tmp, nrow_local=nrow_local, ncol_local=ncol_local, &
238  row_indices=row_indices, col_indices=col_indices, local_data=local_data)
239 
240  !
241  CALL parallel_gemm('T', 'N', n, k, n, 1.0_dp, preconditioner_env%fm, &
242  matrix_in, 0.0_dp, matrix_tmp)
243 
244  ! do the right scaling
245  DO j = 1, ncol_local
246  DO i = 1, nrow_local
247  dum = 1.0_dp/max(preconditioner_env%energy_gap, &
248  preconditioner_env%full_evals(row_indices(i)) - preconditioner_env%occ_evals(col_indices(j)))
249  local_data(i, j) = local_data(i, j)*dum
250  END DO
251  END DO
252 
253  ! mult back
254  CALL parallel_gemm('N', 'N', n, k, n, 1.0_dp, preconditioner_env%fm, &
255  matrix_tmp, 0.0_dp, matrix_out)
256 
257  CALL cp_fm_release(matrix_tmp)
258 
259  CALL timestop(handle)
260 
261  END SUBROUTINE apply_full_all
262 
263 ! **************************************************************************************************
264 !> \brief full all to a dbcsr matrix
265 !> \param preconditioner_env ...
266 !> \param matrix_in ...
267 !> \param matrix_out ...
268 ! **************************************************************************************************
269  SUBROUTINE apply_all(preconditioner_env, matrix_in, matrix_out)
270 
271  TYPE(preconditioner_type) :: preconditioner_env
272  TYPE(dbcsr_type) :: matrix_in, matrix_out
273 
274  CHARACTER(len=*), PARAMETER :: routinen = 'apply_all'
275 
276  INTEGER :: col, col_offset, col_size, handle, i, j, &
277  row, row_offset, row_size
278  REAL(kind=dp) :: dum
279  REAL(kind=dp), DIMENSION(:, :), POINTER :: DATA
280  TYPE(dbcsr_iterator_type) :: iter
281  TYPE(dbcsr_type) :: matrix_tmp
282 
283  CALL timeset(routinen, handle)
284 
285  CALL dbcsr_copy(matrix_tmp, matrix_in, name="apply_full_all")
286  CALL dbcsr_multiply('T', 'N', 1.0_dp, preconditioner_env%dbcsr_matrix, &
287  matrix_in, 0.0_dp, matrix_tmp)
288  ! do the right scaling
289  CALL dbcsr_iterator_start(iter, matrix_tmp)
290  DO WHILE (dbcsr_iterator_blocks_left(iter))
291  CALL dbcsr_iterator_next_block(iter, row, col, DATA, &
292  row_size=row_size, col_size=col_size, &
293  row_offset=row_offset, col_offset=col_offset)
294  DO j = 1, col_size
295  DO i = 1, row_size
296  dum = 1.0_dp/max(preconditioner_env%energy_gap, &
297  preconditioner_env%full_evals(row_offset + i - 1) &
298  - preconditioner_env%occ_evals(col_offset + j - 1))
299  DATA(i, j) = DATA(i, j)*dum
300  END DO
301  END DO
302  END DO
303  CALL dbcsr_iterator_stop(iter)
304 
305  ! mult back
306  CALL dbcsr_multiply('N', 'N', 1.0_dp, preconditioner_env%dbcsr_matrix, &
307  matrix_tmp, 0.0_dp, matrix_out)
308  CALL dbcsr_release(matrix_tmp)
309  CALL timestop(handle)
310 
311  END SUBROUTINE apply_all
312 
313 END MODULE preconditioner_apply
various cholesky decomposition related routines
subroutine, public cp_fm_cholesky_restore(matrix, neig, matrixb, matrixout, op, pos, transa)
...
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
Definition: cp_fm_types.F:1016
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
Definition: cp_fm_types.F:167
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public ot_precond_full_kinetic
integer, parameter, public ot_precond_full_single
integer, parameter, public ot_precond_solver_inv_chol
integer, parameter, public ot_precond_full_single_inverse
integer, parameter, public ot_precond_s_inverse
integer, parameter, public ot_precond_solver_update
integer, parameter, public ot_precond_full_all
integer, parameter, public ot_precond_solver_direct
Defines the basic variable types.
Definition: kinds.F:23
integer, parameter, public dp
Definition: kinds.F:34
basic linear algebra operations for full matrixes
computes preconditioners, and implements methods to apply them currently used in qs_ot
subroutine, public apply_preconditioner_fm(preconditioner_env, matrix_in, matrix_out)
applies a previously created preconditioner to a full matrix
subroutine, public apply_preconditioner_dbcsr(preconditioner_env, matrix_in, matrix_out)
...
types of preconditioners