(git:374b731)
Loading...
Searching...
No Matches
mscfg_types.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 Types used to generate the molecular SCF guess
10!> \par History
11!> 10.2014 created [Rustam Z Khaliullin]
12!> \author Rustam Z Khaliullin
13! **************************************************************************************************
15 USE dbcsr_api, ONLY: &
16 dbcsr_add, dbcsr_complete_redistribute, dbcsr_create, dbcsr_distribution_get, &
17 dbcsr_distribution_new, dbcsr_distribution_release, dbcsr_distribution_type, &
18 dbcsr_finalize, dbcsr_get_info, dbcsr_iterator_blocks_left, dbcsr_iterator_next_block, &
19 dbcsr_iterator_start, dbcsr_iterator_stop, dbcsr_iterator_type, dbcsr_nfullcols_total, &
20 dbcsr_nfullrows_total, dbcsr_release, dbcsr_reserve_block2d, dbcsr_set, dbcsr_type, &
21 dbcsr_type_no_symmetry, dbcsr_work_create
22 USE kinds, ONLY: dp
23#include "./base/base_uses.f90"
24
25 IMPLICIT NONE
26
27 PRIVATE
28
29 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'mscfg_types'
30
31 INTEGER, PARAMETER, PUBLIC :: mscfg_max_moset_size = 2
32
33 ! Public types
35
36 ! Public subroutines
40
41 ! Contains data pertaining to molecular_scf_guess calculations
43
44 ! Useful flags to pass around
45 LOGICAL :: is_fast_dirty, &
46 is_crystal
47
48 ! Real data
49 INTEGER :: nfrags
50 REAL(kind=dp), DIMENSION(:), ALLOCATABLE :: energy_of_frag
51 INTEGER, DIMENSION(:), ALLOCATABLE :: nmosets_of_frag
52 TYPE(dbcsr_type), DIMENSION(:, :), ALLOCATABLE :: mos_of_frag
53
54 END TYPE
55
56CONTAINS
57
58! **************************************************************************************************
59!> \brief Allocates data
60!> \param env ...
61!> \param nfrags number of entries
62!> \par History
63!> 2014.10 created [Rustam Z Khaliullin]
64!> \author Rustam Z Khaliullin
65! **************************************************************************************************
66 SUBROUTINE molecular_scf_guess_env_init(env, nfrags)
67
69 INTEGER, INTENT(IN) :: nfrags
70
71! check if the number of fragments is already set
72!IF (env%nfrags.ne.0) THEN
73! ! do not allow re-initialization
74! ! to prevent recursive calls
75! CPPostcondition(.FALSE.,cp_failure_level,routineP,failure)
76!ENDIF
77
78 env%nfrags = nfrags
79 IF (nfrags .GT. 0) THEN
80 ALLOCATE (env%energy_of_frag(nfrags))
81 ALLOCATE (env%nmosets_of_frag(nfrags))
82 ALLOCATE (env%mos_of_frag(nfrags, mscfg_max_moset_size))
83 END IF
84
85 END SUBROUTINE molecular_scf_guess_env_init
86
87! **************************************************************************************************
88!> \brief Destroyes both data and environment
89!> \param env ...
90!> \par History
91!> 2014.10 created [Rustam Z Khaliullin]
92!> \author Rustam Z Khaliullin
93! **************************************************************************************************
95
97
98 INTEGER :: ifrag, jfrag
99
100 IF (ALLOCATED(env%mos_of_frag)) THEN
101 DO ifrag = 1, SIZE(env%mos_of_frag, 1)
102 DO jfrag = 1, env%nmosets_of_frag(ifrag)
103 CALL dbcsr_release(env%mos_of_frag(ifrag, jfrag))
104 END DO
105 END DO
106 DEALLOCATE (env%mos_of_frag)
107 END IF
108 IF (ALLOCATED(env%energy_of_frag)) DEALLOCATE (env%energy_of_frag)
109 IF (ALLOCATED(env%nmosets_of_frag)) DEALLOCATE (env%nmosets_of_frag)
110
111 env%nfrags = 0
112
114
115! **************************************************************************************************
116!> \brief Creates a distributed matrix from MOs on fragments
117!> \param mscfg_env env containing MOs of fragments
118!> \param matrix_out all existing blocks will be deleted!
119!> \param iset which set of MOs in mscfg_env has to be converted (e.g. spin)
120!> \par History
121!> 10.2014 created [Rustam Z Khaliullin]
122!> \author Rustam Z Khaliullin
123! **************************************************************************************************
124 SUBROUTINE get_matrix_from_submatrices(mscfg_env, matrix_out, iset)
125
126 TYPE(molecular_scf_guess_env_type), INTENT(IN) :: mscfg_env
127 TYPE(dbcsr_type), INTENT(INOUT) :: matrix_out
128 INTEGER, INTENT(IN) :: iset
129
130 CHARACTER(len=*), PARAMETER :: routinen = 'get_matrix_from_submatrices'
131
132 INTEGER :: handle, ifrag
133 INTEGER, DIMENSION(2) :: matrix_size, offset, submatrix_size
134 TYPE(dbcsr_type) :: matrix_temp
135
136 CALL timeset(routinen, handle)
137
138 cpassert(iset .LE. mscfg_max_moset_size)
139
140 CALL dbcsr_create(matrix_temp, &
141 template=matrix_out, &
142 matrix_type=dbcsr_type_no_symmetry)
143 CALL dbcsr_set(matrix_out, 0.0_dp)
144
145 matrix_size(1) = dbcsr_nfullrows_total(matrix_out)
146 matrix_size(2) = dbcsr_nfullcols_total(matrix_out)
147
148 ! assume that the initial offset is zero
149 offset(1) = 0
150 offset(2) = 0
151
152 DO ifrag = 1, mscfg_env%nfrags
153
154 cpassert(iset .LE. mscfg_env%nmosets_of_frag(ifrag))
155
156 submatrix_size(1) = dbcsr_nfullrows_total(mscfg_env%mos_of_frag(ifrag, iset))
157 submatrix_size(2) = dbcsr_nfullcols_total(mscfg_env%mos_of_frag(ifrag, iset))
158
159 CALL copy_submatrix_into_matrix(mscfg_env%mos_of_frag(ifrag, iset), &
160 matrix_temp, offset, submatrix_size, matrix_size)
161
162 CALL dbcsr_add(matrix_out, matrix_temp, 1.0_dp, 1.0_dp)
163
164 offset(1) = offset(1) + submatrix_size(1)
165 offset(2) = offset(2) + submatrix_size(2)
166
167 END DO
168
169 ! Check that the accumulated size of submatrices
170 ! is exactly the same as the size of the big matrix
171 ! This is to prevent unexpected conversion errors
172 ! If however such conversion is intended - remove these safeguards
173 cpassert(offset(1) .EQ. matrix_size(1))
174 cpassert(offset(2) .EQ. matrix_size(2))
175
176 CALL dbcsr_release(matrix_temp)
177
178 CALL timestop(handle)
179
180 END SUBROUTINE get_matrix_from_submatrices
181
182! **************************************************************************************************
183!> \brief Copies a distributed dbcsr submatrix into a distributed dbcsr matrix
184!> \param submatrix_in ...
185!> \param matrix_out all existing blocks will be deleted!
186!> \param offset ...
187!> \param submatrix_size ...
188!> \param matrix_size ...
189!> \par History
190!> 10.2014 created [Rustam Z Khaliullin]
191!> \author Rustam Z Khaliullin
192! **************************************************************************************************
193 SUBROUTINE copy_submatrix_into_matrix(submatrix_in, matrix_out, &
194 offset, submatrix_size, matrix_size)
195
196 TYPE(dbcsr_type), INTENT(IN) :: submatrix_in
197 TYPE(dbcsr_type), INTENT(INOUT) :: matrix_out
198 INTEGER, DIMENSION(2), INTENT(IN) :: offset, submatrix_size, matrix_size
199
200 INTEGER :: add_blocks_after, dimen, iblock_col, &
201 iblock_row, iblock_size, nblocks, &
202 nblocks_new, start_index, trailing_size
203 INTEGER, DIMENSION(2) :: add_blocks_before
204 INTEGER, DIMENSION(:), POINTER :: blk_distr, blk_sizes, block_sizes_new, col_distr_new, &
205 col_sizes_new, distr_new_array, row_distr_new, row_sizes_new
206 REAL(kind=dp), DIMENSION(:, :), POINTER :: data_p, p_new_block
207 TYPE(dbcsr_distribution_type) :: dist_new, dist_qs
208 TYPE(dbcsr_iterator_type) :: iter
209 TYPE(dbcsr_type) :: matrix_new
210
211! obtain distribution of the submatrix
212
213 CALL dbcsr_get_info(submatrix_in, distribution=dist_qs)
214
215 DO dimen = 1, 2 ! 1 - row, 2 - column dimension
216
217 add_blocks_before(dimen) = 0
218 add_blocks_after = 0
219 start_index = 1
220 trailing_size = matrix_size(dimen) - offset(dimen) - submatrix_size(dimen)
221 IF (offset(dimen) .GT. 0) THEN
222 add_blocks_before(dimen) = add_blocks_before(dimen) + 1
223 start_index = 2
224 END IF
225 IF (trailing_size .GT. 0) THEN
226 add_blocks_after = add_blocks_after + 1
227 END IF
228
229 IF (dimen == 1) THEN !rows
230 CALL dbcsr_distribution_get(dist_qs, row_dist=blk_distr)
231 CALL dbcsr_get_info(submatrix_in, row_blk_size=blk_sizes)
232 ELSE !columns
233 CALL dbcsr_distribution_get(dist_qs, col_dist=blk_distr)
234 CALL dbcsr_get_info(submatrix_in, col_blk_size=blk_sizes)
235 END IF
236 nblocks = SIZE(blk_sizes) ! number of blocks in the small matrix
237
238 nblocks_new = nblocks + add_blocks_before(dimen) + add_blocks_after
239 ALLOCATE (block_sizes_new(nblocks_new))
240 ALLOCATE (distr_new_array(nblocks_new))
241 !IF (ASSOCIATED(cluster_distr)) THEN
242 !ALLOCATE (cluster_distr_new(nblocks_new))
243 !END IF
244 IF (add_blocks_before(dimen) .GT. 0) THEN
245 block_sizes_new(1) = offset(dimen)
246 distr_new_array(1) = 0
247 !IF (ASSOCIATED(cluster_distr)) THEN
248 !cluster_distr_new(1) = 0
249 !END IF
250 END IF
251 block_sizes_new(start_index:nblocks + start_index - 1) = blk_sizes(1:nblocks)
252 distr_new_array(start_index:nblocks + start_index - 1) = blk_distr(1:nblocks)
253 !IF (ASSOCIATED(cluster_distr)) THEN
254 !cluster_distr_new(start_index:nblocks+start_index-1) = cluster_distr(1:nblocks)
255 !END IF
256 IF (add_blocks_after .GT. 0) THEN
257 block_sizes_new(nblocks_new) = trailing_size
258 distr_new_array(nblocks_new) = 0
259 !IF (ASSOCIATED(cluster_distr)) THEN
260 !cluster_distr_new(nblocks_new) = 0
261 !END IF
262 END IF
263
264 ! create final arrays
265 IF (dimen == 1) THEN !rows
266 row_sizes_new => block_sizes_new
267 row_distr_new => distr_new_array
268 !row_cluster_new => cluster_distr_new
269 ELSE !columns
270 col_sizes_new => block_sizes_new
271 col_distr_new => distr_new_array
272 !col_cluster_new => cluster_distr_new
273 END IF
274 END DO ! both rows and columns are done
275
276 ! Create the distribution
277 CALL dbcsr_distribution_new(dist_new, template=dist_qs, &
278 row_dist=row_distr_new, col_dist=col_distr_new, &
279 !row_cluster=row_cluster_new, col_cluster=col_cluster_new, &
280 reuse_arrays=.true.)
281
282 ! Create big the matrix
283 CALL dbcsr_create(matrix_new, "BIG_AND_FAKE", &
284 dist_new, dbcsr_type_no_symmetry, &
285 row_sizes_new, col_sizes_new, &
286 reuse_arrays=.true.)
287 CALL dbcsr_distribution_release(dist_new)
288
289 !CALL dbcsr_finalize(matrix_new)
290
291 ! copy blocks of the small matrix to the big matrix
292 !mynode = dbcsr_mp_mynode(dbcsr_distribution_mp(dbcsr_distribution(matrix_new)))
293 CALL dbcsr_work_create(matrix_new, work_mutable=.true.)
294
295 ! iterate over local blocks of the small matrix
296 CALL dbcsr_iterator_start(iter, submatrix_in)
297
298 DO WHILE (dbcsr_iterator_blocks_left(iter))
299
300 CALL dbcsr_iterator_next_block(iter, iblock_row, iblock_col, data_p, row_size=iblock_size)
301
302 ! it is important that distribution of the big matrix is the same as
303 ! that of the small matrix but has the same number of columns and rows
304 ! as the super-system matrix. this is necessary for complete redistribute
305 ! to work
306 NULLIFY (p_new_block)
307 CALL dbcsr_reserve_block2d(matrix_new, &
308 iblock_row + add_blocks_before(1), &
309 iblock_col + add_blocks_before(2), &
310 p_new_block)
311
312 cpassert(ASSOCIATED(p_new_block))
313 cpassert(SIZE(p_new_block, 1) .EQ. SIZE(data_p, 1))
314 cpassert(SIZE(p_new_block, 2) .EQ. SIZE(data_p, 2))
315
316 p_new_block(:, :) = data_p(:, :)
317
318 END DO
319 CALL dbcsr_iterator_stop(iter)
320
321 CALL dbcsr_finalize(matrix_new)
322
323 ! finally call complete redistribute to get the matrix of the entire system
324 CALL dbcsr_set(matrix_out, 0.0_dp)
325 CALL dbcsr_complete_redistribute(matrix_new, matrix_out)
326 CALL dbcsr_release(matrix_new)
327
328 END SUBROUTINE copy_submatrix_into_matrix
329
330END MODULE mscfg_types
331
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Types used to generate the molecular SCF guess.
Definition mscfg_types.F:14
integer, parameter, public mscfg_max_moset_size
Definition mscfg_types.F:31
subroutine, public get_matrix_from_submatrices(mscfg_env, matrix_out, iset)
Creates a distributed matrix from MOs on fragments.
subroutine, public molecular_scf_guess_env_destroy(env)
Destroyes both data and environment.
Definition mscfg_types.F:95
subroutine, public molecular_scf_guess_env_init(env, nfrags)
Allocates data.
Definition mscfg_types.F:67