Line data Source code
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 New version of the module for the localization of the molecular orbitals
10 : !> This should be able to use different definition of the spread functional
11 : !> It should also calculate the integrals analytically so that it can be
12 : !> used irrespective of the pw_env and the collocation of wfn on the grids
13 : !> It should also work with a selected set of states, instead than all of them,
14 : !> in this case one should check that the selected states have the same occupation number
15 : !> The spread functional can be only estimated, or also optimized by minimization
16 : !> and in principle also maximization should be available.
17 : !> This operations can be required irrespective of the printing requirements
18 : !> It would be highly desirable to do all this along a MD run every N steps,
19 : !> and have a trajectory of the centeroids of the localized wfn
20 : !> In addition these functions can be used for properties calculations
21 : !> like NMR and XAS. Therefore it is necessary that the rotated wfn are then copied
22 : !> in the mos fm matrix to be available for next use.
23 : !> \author MI (05-2005)
24 : ! **************************************************************************************************
25 : MODULE qs_loc_types
26 :
27 : USE cell_types, ONLY: cell_release,&
28 : cell_retain,&
29 : cell_type
30 : USE cp_array_utils, ONLY: cp_2d_r_p_type
31 : USE cp_dbcsr_api, ONLY: dbcsr_deallocate_matrix,&
32 : dbcsr_p_type
33 : USE cp_fm_types, ONLY: cp_fm_release,&
34 : cp_fm_type
35 : USE distribution_1d_types, ONLY: distribution_1d_release,&
36 : distribution_1d_retain,&
37 : distribution_1d_type
38 : USE kinds, ONLY: default_string_length,&
39 : dp
40 : USE message_passing, ONLY: mp_para_env_release,&
41 : mp_para_env_type
42 : USE particle_types, ONLY: particle_type
43 : #include "./base/base_uses.f90"
44 :
45 : IMPLICIT NONE
46 :
47 : PRIVATE
48 :
49 : ! *** Global parameters ***
50 :
51 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_loc_types'
52 :
53 : ! **************************************************************************************************
54 : !> \brief contains all the info needed by quickstep to calculate
55 : !> the spread of a selected set of orbitals and if required
56 : !> to minimize or maximize the spread by rotation of the orbitals
57 : !> \param para_env info for the distribution of the calculations
58 : !> \param mo_coeff full matrix containing only the selected subset of real orbitals
59 : !> \param complex_mo_coeff full matrix containing only the selected subset of complex orbitals
60 : !> \param local_molecules molecules distributed
61 : !> \param cell box that contains the system
62 : !> \param localized_wfn_control variables and parameter that define the spread
63 : !> functional and the optimization algorithm
64 : !> \param particle_set position, type, ao_indexes etc for each atom
65 : !> \param op_sm_set set of sparse matrices used to define the spread operator
66 : !> when the functional is defined by the use operator acting on the
67 : !> basis functions, e.g. the Berry phase definition
68 : !> The matrix element of the type <a|O|b> are computed in initialization
69 : !> of qs_loc_env
70 : !> \param op_fm_set set of full matrices used to define the spread operator
71 : !> when the functional has to be defined directly using the products of MOS
72 : !> as in the case of the Pipek-Mezek definition.
73 : !> \param weights for a spread defined as extension of the orbitral in the box, these
74 : !> factors renormalize with respect to the box size
75 : !> \note
76 : !> this type should replace the previous set up for the localization of the wfn
77 : !> \par History
78 : !> 04-05 created
79 : !> \author MI
80 : ! **************************************************************************************************
81 : TYPE qs_loc_env_type
82 : LOGICAL :: do_localize = .FALSE., first_time = .FALSE.
83 : LOGICAL :: molecular_states = .FALSE.
84 : LOGICAL :: wannier_states = .FALSE.
85 : CHARACTER(LEN=default_string_length) :: tag_mo = ""
86 : TYPE(mp_para_env_type), POINTER :: para_env => NULL()
87 : TYPE(cp_fm_type), DIMENSION(:), &
88 : POINTER :: moloc_coeff => NULL()
89 : TYPE(cp_fm_type), DIMENSION(:, :), &
90 : POINTER :: op_fm_set => NULL()
91 : TYPE(distribution_1d_type), POINTER :: local_molecules => NULL()
92 : TYPE(cell_type), POINTER :: cell => NULL()
93 : TYPE(localized_wfn_control_type), &
94 : POINTER :: localized_wfn_control => NULL()
95 : TYPE(particle_type), DIMENSION(:), &
96 : POINTER :: particle_set => NULL()
97 : TYPE(dbcsr_p_type), DIMENSION(:, :), &
98 : POINTER :: op_sm_set => NULL()
99 : REAL(KIND=dp) :: start_time = -1.0_dp, target_time = -1.0_dp
100 : REAL(KIND=dp) :: weights(6) = -1.0_dp
101 : INTEGER :: dim_op = -1
102 : END TYPE qs_loc_env_type
103 :
104 : ! **************************************************************************************************
105 : !> \brief A type that holds controlling information for the
106 : !> calculation of the spread of wfn and the optimization of
107 : !> the spread functional
108 : !> \param ref_count ...
109 : !> \param localization_method which algorithm is used for the optimization
110 : !> \param operator_type how the spread is defined
111 : !> \param nloc_states number of states on which the spread is computed
112 : !> \param set_of_states how to choose the states
113 : !> \param lu_bound_states lower and upper bounds of the set of states
114 : !> print_cubes:
115 : !> print_centers:
116 : !> print_spreads:
117 : !> \param loc_states list of states on which the spread is computed
118 : !> \param centers_set arrais containing centers and spreads of the selected wfn
119 : !> \param centers_file_name output file names
120 : !> \param spreads_file_name output file names
121 : ! **************************************************************************************************
122 : TYPE localized_wfn_control_type
123 : INTEGER :: ref_count = -1
124 : INTEGER :: min_or_max = -1
125 : INTEGER :: localization_method = -1
126 : INTEGER :: operator_type = -1
127 : INTEGER, DIMENSION(2) :: nloc_states = -1, nguess = -1
128 : INTEGER :: set_of_states = -1
129 : INTEGER, DIMENSION(2, 2) :: lu_bound_states = -1
130 : INTEGER :: max_iter = -1
131 : INTEGER :: out_each = -1
132 : INTEGER :: nextra = -1
133 : INTEGER :: coeff_po_guess = -1, coeff_po_guess_mo_space = -1
134 : REAL(KIND=dp) :: eps_localization = -1.0_dp
135 : REAL(KIND=dp) :: max_crazy_angle = -1.0_dp
136 : REAL(KIND=dp) :: crazy_scale = -1.0_dp
137 : REAL(KIND=dp) :: eps_occ = -1.0_dp
138 : REAL(KIND=dp), DIMENSION(2) :: lu_ene_bound = -1.0_dp
139 : LOGICAL :: crazy_use_diag = .FALSE.
140 : LOGICAL :: print_cubes = .FALSE., jacobi_fallback = .FALSE., jacobi_refinement = .FALSE.
141 : LOGICAL :: print_centers = .FALSE.
142 : LOGICAL :: print_spreads = .FALSE.
143 : LOGICAL :: do_homo = .FALSE.
144 : LOGICAL :: do_mixed = .FALSE., do_cg_po = .FALSE.
145 : LOGICAL :: loc_restart = .FALSE.
146 : LOGICAL :: use_history = .FALSE.
147 : INTEGER, POINTER, DIMENSION(:, :) :: loc_states => NULL()
148 : TYPE(cp_2d_r_p_type), DIMENSION(2) :: centers_set = cp_2d_r_p_type()
149 : END TYPE localized_wfn_control_type
150 :
151 : ! *** Public ***
152 : PUBLIC :: qs_loc_env_create, qs_loc_env_release, &
153 : get_qs_loc_env, set_qs_loc_env, &
154 : localized_wfn_control_create, localized_wfn_control_release
155 : PUBLIC :: qs_loc_env_type, localized_wfn_control_type
156 :
157 : CONTAINS
158 :
159 : ! **************************************************************************************************
160 : !> \brief ...
161 : !> \param qs_loc_env ...
162 : !> \par History
163 : !> 04-05 created
164 : !> \author MI
165 : ! **************************************************************************************************
166 3724 : SUBROUTINE qs_loc_env_create(qs_loc_env)
167 :
168 : TYPE(qs_loc_env_type), INTENT(OUT) :: qs_loc_env
169 :
170 532 : qs_loc_env%tag_mo = ""
171 : NULLIFY (qs_loc_env%para_env)
172 : NULLIFY (qs_loc_env%cell)
173 : NULLIFY (qs_loc_env%op_sm_set)
174 : NULLIFY (qs_loc_env%op_fm_set)
175 : NULLIFY (qs_loc_env%local_molecules)
176 : NULLIFY (qs_loc_env%moloc_coeff)
177 : NULLIFY (qs_loc_env%particle_set)
178 : NULLIFY (qs_loc_env%localized_wfn_control)
179 3724 : qs_loc_env%weights = 0.0_dp
180 :
181 532 : END SUBROUTINE qs_loc_env_create
182 :
183 : !****f* qs_loc_types/qs_loc_env_release [1.0] *
184 :
185 : ! **************************************************************************************************
186 : !> \brief ...
187 : !> \param qs_loc_env ...
188 : !> \par History
189 : !> 04-05 created
190 : !> \author MI
191 : ! **************************************************************************************************
192 532 : SUBROUTINE qs_loc_env_release(qs_loc_env)
193 :
194 : TYPE(qs_loc_env_type), INTENT(INOUT) :: qs_loc_env
195 :
196 : INTEGER :: i, ii, j
197 :
198 532 : IF (ASSOCIATED(qs_loc_env%cell)) CALL cell_release(qs_loc_env%cell)
199 532 : IF (ASSOCIATED(qs_loc_env%local_molecules)) THEN
200 484 : CALL distribution_1d_release(qs_loc_env%local_molecules)
201 : END IF
202 532 : IF (ASSOCIATED(qs_loc_env%localized_wfn_control)) THEN
203 532 : CALL localized_wfn_control_release(qs_loc_env%localized_wfn_control)
204 : END IF
205 532 : IF (ASSOCIATED(qs_loc_env%para_env)) CALL mp_para_env_release(qs_loc_env%para_env)
206 532 : IF (ASSOCIATED(qs_loc_env%particle_set)) NULLIFY (qs_loc_env%particle_set)
207 :
208 532 : IF (ASSOCIATED(qs_loc_env%moloc_coeff)) THEN
209 1146 : DO i = 1, SIZE(qs_loc_env%moloc_coeff, 1)
210 662 : ii = LBOUND(qs_loc_env%moloc_coeff, 1) + i - 1
211 1146 : CALL cp_fm_release(qs_loc_env%moloc_coeff(ii))
212 : END DO
213 484 : DEALLOCATE (qs_loc_env%moloc_coeff)
214 : END IF
215 :
216 532 : CALL cp_fm_release(qs_loc_env%op_fm_set)
217 :
218 532 : IF (ASSOCIATED(qs_loc_env%op_sm_set)) THEN
219 1948 : DO i = 1, SIZE(qs_loc_env%op_sm_set, 2)
220 4888 : DO j = 1, SIZE(qs_loc_env%op_sm_set, 1)
221 4410 : CALL dbcsr_deallocate_matrix(qs_loc_env%op_sm_set(j, i)%matrix)
222 : END DO
223 : END DO
224 478 : DEALLOCATE (qs_loc_env%op_sm_set)
225 : END IF
226 :
227 532 : END SUBROUTINE qs_loc_env_release
228 :
229 : ! **************************************************************************************************
230 : !> \brief create the localized_wfn_control_type
231 : !> \param localized_wfn_control ...
232 : !> \par History
233 : !> 04.2005 created [MI]
234 : ! **************************************************************************************************
235 532 : SUBROUTINE localized_wfn_control_create(localized_wfn_control)
236 : TYPE(localized_wfn_control_type), POINTER :: localized_wfn_control
237 :
238 532 : CPASSERT(.NOT. ASSOCIATED(localized_wfn_control))
239 10640 : ALLOCATE (localized_wfn_control)
240 :
241 532 : localized_wfn_control%ref_count = 1
242 1596 : localized_wfn_control%nloc_states = 0
243 532 : localized_wfn_control%nextra = 0
244 1596 : localized_wfn_control%nguess = 0
245 3724 : localized_wfn_control%lu_bound_states = 0
246 1596 : localized_wfn_control%lu_ene_bound = 0.0_dp
247 532 : localized_wfn_control%print_cubes = .FALSE.
248 532 : localized_wfn_control%print_centers = .FALSE.
249 532 : localized_wfn_control%print_spreads = .FALSE.
250 532 : localized_wfn_control%do_homo = .TRUE.
251 532 : localized_wfn_control%use_history = .FALSE.
252 532 : NULLIFY (localized_wfn_control%loc_states)
253 532 : NULLIFY (localized_wfn_control%centers_set(1)%array)
254 532 : NULLIFY (localized_wfn_control%centers_set(2)%array)
255 532 : END SUBROUTINE localized_wfn_control_create
256 :
257 : ! **************************************************************************************************
258 : !> \brief release the localized_wfn_control_type
259 : !> \param localized_wfn_control ...
260 : !> \par History
261 : !> 04.2005 created [MI]
262 : ! **************************************************************************************************
263 1880 : SUBROUTINE localized_wfn_control_release(localized_wfn_control)
264 :
265 : TYPE(localized_wfn_control_type), POINTER :: localized_wfn_control
266 :
267 1880 : IF (ASSOCIATED(localized_wfn_control)) THEN
268 1448 : CPASSERT(localized_wfn_control%ref_count > 0)
269 1448 : localized_wfn_control%ref_count = localized_wfn_control%ref_count - 1
270 1448 : IF (localized_wfn_control%ref_count == 0) THEN
271 532 : IF (ASSOCIATED(localized_wfn_control%loc_states)) THEN
272 450 : DEALLOCATE (localized_wfn_control%loc_states)
273 : END IF
274 532 : IF (ASSOCIATED(localized_wfn_control%centers_set(1)%array)) THEN
275 484 : DEALLOCATE (localized_wfn_control%centers_set(1)%array)
276 : END IF
277 532 : IF (ASSOCIATED(localized_wfn_control%centers_set(2)%array)) THEN
278 176 : DEALLOCATE (localized_wfn_control%centers_set(2)%array)
279 : END IF
280 532 : localized_wfn_control%ref_count = 0
281 532 : DEALLOCATE (localized_wfn_control)
282 : END IF
283 : END IF
284 1880 : END SUBROUTINE localized_wfn_control_release
285 :
286 : ! **************************************************************************************************
287 : !> \brief retain the localized_wfn_control_type
288 : !> \param localized_wfn_control ...
289 : !> \par History
290 : !> 04.2005 created [MI]
291 : ! **************************************************************************************************
292 916 : SUBROUTINE localized_wfn_control_retain(localized_wfn_control)
293 : TYPE(localized_wfn_control_type), POINTER :: localized_wfn_control
294 :
295 916 : CPASSERT(ASSOCIATED(localized_wfn_control))
296 :
297 916 : localized_wfn_control%ref_count = localized_wfn_control%ref_count + 1
298 916 : END SUBROUTINE localized_wfn_control_retain
299 :
300 : ! **************************************************************************************************
301 : !> \brief ...
302 : !> \param qs_loc_env ...
303 : !> \param cell ...
304 : !> \param local_molecules ...
305 : !> \param localized_wfn_control ...
306 : !> \param moloc_coeff ...
307 : !> \param op_sm_set ...
308 : !> \param op_fm_set ...
309 : !> \param para_env ...
310 : !> \param particle_set ...
311 : !> \param weights ...
312 : !> \param dim_op ...
313 : !> \par History
314 : !> 04-05 created
315 : !> \author MI
316 : ! **************************************************************************************************
317 2200 : SUBROUTINE get_qs_loc_env(qs_loc_env, cell, local_molecules, localized_wfn_control, &
318 : moloc_coeff, op_sm_set, op_fm_set, para_env, &
319 : particle_set, weights, dim_op)
320 :
321 : TYPE(qs_loc_env_type), INTENT(IN) :: qs_loc_env
322 : TYPE(cell_type), OPTIONAL, POINTER :: cell
323 : TYPE(distribution_1d_type), OPTIONAL, POINTER :: local_molecules
324 : TYPE(localized_wfn_control_type), OPTIONAL, &
325 : POINTER :: localized_wfn_control
326 : TYPE(cp_fm_type), DIMENSION(:), OPTIONAL, POINTER :: moloc_coeff
327 : TYPE(dbcsr_p_type), DIMENSION(:, :), OPTIONAL, &
328 : POINTER :: op_sm_set
329 : TYPE(cp_fm_type), DIMENSION(:, :), OPTIONAL, &
330 : POINTER :: op_fm_set
331 : TYPE(mp_para_env_type), OPTIONAL, POINTER :: para_env
332 : TYPE(particle_type), DIMENSION(:), OPTIONAL, &
333 : POINTER :: particle_set
334 : REAL(dp), DIMENSION(6), OPTIONAL :: weights
335 : INTEGER, OPTIONAL :: dim_op
336 :
337 2200 : IF (PRESENT(cell)) cell => qs_loc_env%cell
338 2200 : IF (PRESENT(moloc_coeff)) moloc_coeff => qs_loc_env%moloc_coeff
339 2200 : IF (PRESENT(local_molecules)) local_molecules => qs_loc_env%local_molecules
340 2200 : IF (PRESENT(localized_wfn_control)) THEN
341 1622 : localized_wfn_control => qs_loc_env%localized_wfn_control
342 : END IF
343 2200 : IF (PRESENT(op_sm_set)) op_sm_set => qs_loc_env%op_sm_set
344 2200 : IF (PRESENT(op_fm_set)) op_fm_set => qs_loc_env%op_fm_set
345 2200 : IF (PRESENT(para_env)) para_env => qs_loc_env%para_env
346 2200 : IF (PRESENT(particle_set)) particle_set => qs_loc_env%particle_set
347 6456 : IF (PRESENT(weights)) weights(1:6) = qs_loc_env%weights(1:6)
348 2200 : IF (PRESENT(dim_op)) dim_op = qs_loc_env%dim_op
349 :
350 2200 : END SUBROUTINE get_qs_loc_env
351 :
352 : ! **************************************************************************************************
353 : !> \brief ...
354 : !> \param qs_loc_env ...
355 : !> \param cell ...
356 : !> \param local_molecules ...
357 : !> \param localized_wfn_control ...
358 : !> \param moloc_coeff ...
359 : !> \param op_sm_set ...
360 : !> \param op_fm_set ...
361 : !> \param para_env ...
362 : !> \param particle_set ...
363 : !> \param weights ...
364 : !> \param dim_op ...
365 : !> \par History
366 : !> 04-05 created
367 : !> \author MI
368 : ! **************************************************************************************************
369 1400 : SUBROUTINE set_qs_loc_env(qs_loc_env, cell, local_molecules, localized_wfn_control, &
370 : moloc_coeff, op_sm_set, op_fm_set, para_env, &
371 : particle_set, weights, dim_op)
372 :
373 : TYPE(qs_loc_env_type), INTENT(INOUT) :: qs_loc_env
374 : TYPE(cell_type), OPTIONAL, POINTER :: cell
375 : TYPE(distribution_1d_type), OPTIONAL, POINTER :: local_molecules
376 : TYPE(localized_wfn_control_type), OPTIONAL, &
377 : POINTER :: localized_wfn_control
378 : TYPE(cp_fm_type), DIMENSION(:), OPTIONAL, POINTER :: moloc_coeff
379 : TYPE(dbcsr_p_type), DIMENSION(:, :), OPTIONAL, &
380 : POINTER :: op_sm_set
381 : TYPE(cp_fm_type), DIMENSION(:, :), OPTIONAL, &
382 : POINTER :: op_fm_set
383 : TYPE(mp_para_env_type), OPTIONAL, POINTER :: para_env
384 : TYPE(particle_type), DIMENSION(:), OPTIONAL, &
385 : POINTER :: particle_set
386 : REAL(dp), DIMENSION(6), OPTIONAL :: weights
387 : INTEGER, OPTIONAL :: dim_op
388 :
389 1400 : IF (PRESENT(cell)) THEN
390 484 : CALL cell_retain(cell)
391 484 : CALL cell_release(qs_loc_env%cell)
392 484 : qs_loc_env%cell => cell
393 : END IF
394 :
395 1400 : IF (PRESENT(local_molecules)) THEN
396 484 : CALL distribution_1d_retain(local_molecules)
397 484 : IF (ASSOCIATED(qs_loc_env%local_molecules)) THEN
398 0 : CALL distribution_1d_release(qs_loc_env%local_molecules)
399 : END IF
400 484 : qs_loc_env%local_molecules => local_molecules
401 : END IF
402 :
403 1400 : IF (PRESENT(localized_wfn_control)) THEN
404 916 : CALL localized_wfn_control_retain(localized_wfn_control)
405 916 : CALL localized_wfn_control_release(qs_loc_env%localized_wfn_control)
406 916 : qs_loc_env%localized_wfn_control => localized_wfn_control
407 : END IF
408 1400 : IF (PRESENT(para_env)) THEN
409 484 : CALL para_env%retain()
410 484 : CALL mp_para_env_release(qs_loc_env%para_env)
411 484 : qs_loc_env%para_env => para_env
412 : END IF
413 1400 : IF (PRESENT(particle_set)) qs_loc_env%particle_set => particle_set
414 1400 : IF (PRESENT(moloc_coeff)) THEN
415 484 : CALL cp_fm_release(qs_loc_env%moloc_coeff)
416 484 : qs_loc_env%moloc_coeff => moloc_coeff
417 : END IF
418 1400 : IF (PRESENT(op_sm_set)) THEN
419 0 : qs_loc_env%op_sm_set => op_sm_set
420 : END IF
421 1400 : IF (PRESENT(op_fm_set)) THEN
422 0 : qs_loc_env%op_fm_set => op_fm_set
423 : END IF
424 1400 : IF (PRESENT(weights)) THEN
425 0 : qs_loc_env%weights = weights
426 : END IF
427 1400 : IF (PRESENT(dim_op)) THEN
428 484 : qs_loc_env%dim_op = dim_op
429 : END IF
430 :
431 1400 : END SUBROUTINE set_qs_loc_env
432 :
433 0 : END MODULE qs_loc_types
434 :
|