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