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 interpolate the wavefunctions to speed up the convergence when
10 : !> doing MD
11 : !> \par History
12 : !> 12.2002 created [fawzi]
13 : !> 02.2005 wf_mol added [MI]
14 : !> \author fawzi
15 : ! **************************************************************************************************
16 : MODULE qs_wf_history_types
17 : USE cp_cfm_types, ONLY: cp_cfm_release,&
18 : cp_cfm_type
19 : USE cp_dbcsr_api, ONLY: dbcsr_deallocate_matrix,&
20 : dbcsr_p_type,&
21 : dbcsr_type
22 : USE cp_dbcsr_operations, ONLY: dbcsr_deallocate_matrix_set
23 : USE cp_fm_types, ONLY: cp_fm_release,&
24 : cp_fm_type
25 : USE kinds, ONLY: dp
26 : USE pw_types, ONLY: pw_c1d_gs_type,&
27 : pw_r3d_rs_type
28 : USE qs_rho_types, ONLY: qs_rho_release,&
29 : qs_rho_type
30 : #include "./base/base_uses.f90"
31 :
32 : IMPLICIT NONE
33 : PRIVATE
34 :
35 : LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .TRUE.
36 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_wf_history_types'
37 :
38 : PUBLIC :: qs_wf_snapshot_type, &
39 : qs_wf_history_type, qs_wf_history_p_type
40 : PUBLIC :: wfi_retain, wfi_release, wfi_clear, wfi_get_snapshot
41 :
42 : ! **************************************************************************************************
43 : !> \brief represent a past snapshot of the wavefunction.
44 : !> some elements might not be associated (to spare memory)
45 : !> depending on how the snapshot was taken
46 : !> \param wf the wavefunctions
47 : !> \param rho_r the density in r space
48 : !> \param rho_g the density in g space
49 : !> \param rho_ao the density in ao space
50 : !> \param overlap the overlap matrix
51 : !> \param wf_kp real k-point MO snapshots
52 : !> \param wf_kp_cfm complex k-point MO snapshots
53 : !> \param rho_frozen the frozen density structure
54 : !> \param dt the time of the snapshot (wrf to te previous snapshot!)
55 : !> \note
56 : !> keep track also of occupation numbers and energies?
57 : !> \par History
58 : !> 02.2003 created [fawzi]
59 : !> 02.2005 wf_mol added [MI]
60 : !> \author fawzi
61 : ! **************************************************************************************************
62 : TYPE qs_wf_snapshot_type
63 : TYPE(cp_fm_type), DIMENSION(:), POINTER :: wf => NULL()
64 : TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: rho_r => NULL()
65 : TYPE(pw_c1d_gs_type), DIMENSION(:), POINTER :: rho_g => NULL()
66 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: rho_ao => NULL()
67 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: rho_ao_kp => NULL()
68 : TYPE(dbcsr_type), POINTER :: overlap => NULL()
69 : TYPE(cp_fm_type), DIMENSION(:, :), POINTER :: wf_kp => NULL()
70 : TYPE(cp_cfm_type), DIMENSION(:, :), POINTER :: wf_kp_cfm => NULL()
71 : TYPE(cp_cfm_type), DIMENSION(:), POINTER :: overlap_cfm_kp => NULL()
72 : INTEGER, DIMENSION(:, :), POINTER :: kp_pbc_shift => NULL()
73 : TYPE(qs_rho_type), POINTER :: rho_frozen => NULL()
74 : REAL(KIND=dp) :: dt = 0.0_dp
75 : END TYPE qs_wf_snapshot_type
76 :
77 : ! **************************************************************************************************
78 : !> \brief pointer to a snapshot
79 : !> \param snapshot the pointer to the snapshot
80 : !> \par History
81 : !> 02.2003 created [fawzi]
82 : !> \author fawzi
83 : ! **************************************************************************************************
84 : TYPE qs_wf_snapshot_p_type
85 : TYPE(qs_wf_snapshot_type), POINTER :: snapshot => NULL()
86 : END TYPE qs_wf_snapshot_p_type
87 :
88 : ! **************************************************************************************************
89 : !> \brief keeps track of the previous wavefunctions and can extrapolate them
90 : !> for the next step of md
91 : !> \param ref_cont reference count (see doc/ReferenceCounting.html)
92 : !> \param memory_depth how many snapshots should be stored
93 : !> \param last_state_index index of the latest snapshot
94 : !> \param past_states array with the past states (index starts at
95 : !> last_state_index)
96 : !> \param interpolation_method_nr the tag of the method used to
97 : !> extrapolate the new start state for qs
98 : !> \param snapshot_count number of snapshot taken so far (cumulative,
99 : !> can be bigger than the history depth)
100 : !> \note
101 : !> use a linked list for the past states ?
102 : !> \par History
103 : !> 02.2003 created [fawzi]
104 : !> \author fawzi
105 : ! **************************************************************************************************
106 : TYPE qs_wf_history_type
107 : INTEGER :: ref_count = -1, memory_depth = -1, last_state_index = -1, &
108 : interpolation_method_nr = -1, snapshot_count = -1
109 : LOGICAL :: store_wf = .FALSE., store_rho_r = .FALSE., store_rho_g = .FALSE., &
110 : store_rho_ao = .FALSE., store_rho_ao_kp = .FALSE., &
111 : store_overlap = .FALSE., store_wf_kp = .FALSE., store_overlap_kp = .FALSE., &
112 : store_frozen_density = .FALSE.
113 : TYPE(qs_wf_snapshot_p_type), DIMENSION(:), POINTER :: past_states => NULL()
114 : END TYPE qs_wf_history_type
115 :
116 : ! **************************************************************************************************
117 : !> \brief to create arrays of pointers to qs_wf_history_type
118 : !> \param wf_hist the pointer to the wf history
119 : !> \author fawzi
120 : ! **************************************************************************************************
121 : TYPE qs_wf_history_p_type
122 : TYPE(qs_wf_history_type), POINTER :: wf_history => NULL()
123 : END TYPE qs_wf_history_p_type
124 :
125 : CONTAINS
126 :
127 : ! **************************************************************************************************
128 : !> \brief releases a snapshot of a wavefunction (see doc/ReferenceCounting.html)
129 : !> \param snapshot the snapshot to release
130 : !> \par History
131 : !> 02.2003 created [fawzi]
132 : !> 02.2005 wf_mol added [MI]
133 : !> \author fawzi
134 : ! **************************************************************************************************
135 12371 : SUBROUTINE wfs_release(snapshot)
136 : TYPE(qs_wf_snapshot_type), INTENT(INOUT) :: snapshot
137 :
138 : INTEGER :: i, ikp, ispin
139 :
140 12371 : CALL cp_fm_release(snapshot%wf)
141 : ! snapshot%rho_r & snapshot%rho_g is deallocated in wfs_update
142 : ! of qs_wf_history_methods, in case you wonder about it.
143 12371 : IF (ASSOCIATED(snapshot%rho_ao)) THEN
144 50 : CALL dbcsr_deallocate_matrix_set(snapshot%rho_ao)
145 : END IF
146 12371 : IF (ASSOCIATED(snapshot%rho_ao_kp)) THEN
147 12 : CALL dbcsr_deallocate_matrix_set(snapshot%rho_ao_kp)
148 : END IF
149 12371 : IF (ASSOCIATED(snapshot%overlap)) THEN
150 8989 : CALL dbcsr_deallocate_matrix(snapshot%overlap)
151 : END IF
152 12371 : IF (ASSOCIATED(snapshot%wf_kp)) THEN
153 0 : CALL cp_fm_release(snapshot%wf_kp)
154 : END IF
155 12371 : IF (ASSOCIATED(snapshot%wf_kp_cfm)) THEN
156 6649 : DO ikp = 1, SIZE(snapshot%wf_kp_cfm, 1)
157 11574 : DO ispin = 1, SIZE(snapshot%wf_kp_cfm, 2)
158 9168 : CALL cp_cfm_release(snapshot%wf_kp_cfm(ikp, ispin))
159 : END DO
160 : END DO
161 2406 : DEALLOCATE (snapshot%wf_kp_cfm)
162 : END IF
163 12371 : IF (ASSOCIATED(snapshot%overlap_cfm_kp)) THEN
164 6639 : DO i = 1, SIZE(snapshot%overlap_cfm_kp)
165 6639 : CALL cp_cfm_release(snapshot%overlap_cfm_kp(i))
166 : END DO
167 2404 : DEALLOCATE (snapshot%overlap_cfm_kp)
168 : END IF
169 12371 : IF (ASSOCIATED(snapshot%kp_pbc_shift)) THEN
170 2406 : DEALLOCATE (snapshot%kp_pbc_shift)
171 : END IF
172 12371 : IF (ASSOCIATED(snapshot%rho_frozen)) THEN
173 4 : CALL qs_rho_release(snapshot%rho_frozen)
174 4 : DEALLOCATE (snapshot%rho_frozen)
175 : END IF
176 :
177 12371 : END SUBROUTINE wfs_release
178 :
179 : ! **************************************************************************************************
180 : !> \brief retains a wf history (see doc/ReferenceCounting.html)
181 : !> \param wf_history the wf_history to retain
182 : !> \par History
183 : !> 02.2003 created [fawzi]
184 : !> \author fawzi
185 : ! **************************************************************************************************
186 9649 : SUBROUTINE wfi_retain(wf_history)
187 : TYPE(qs_wf_history_type), POINTER :: wf_history
188 :
189 9649 : CPASSERT(ASSOCIATED(wf_history))
190 9649 : wf_history%ref_count = wf_history%ref_count + 1
191 :
192 9649 : END SUBROUTINE wfi_retain
193 :
194 : ! **************************************************************************************************
195 : !> \brief releases a wf_history of a wavefunction
196 : !> (see doc/ReferenceCounting.html)
197 : !> \param wf_history the wf_history to release
198 : !> \par History
199 : !> 02.2003 created [fawzi]
200 : !> \author fawzi
201 : ! **************************************************************************************************
202 28221 : SUBROUTINE wfi_release(wf_history)
203 : TYPE(qs_wf_history_type), POINTER :: wf_history
204 :
205 : INTEGER :: i
206 :
207 28221 : IF (ASSOCIATED(wf_history)) THEN
208 18901 : CPASSERT(wf_history%ref_count > 0)
209 18901 : wf_history%ref_count = wf_history%ref_count - 1
210 18901 : IF (wf_history%ref_count == 0) THEN
211 9252 : IF (ASSOCIATED(wf_history%past_states)) THEN
212 52757 : DO i = 1, SIZE(wf_history%past_states)
213 52757 : IF (ASSOCIATED(wf_history%past_states(i)%snapshot)) THEN
214 10367 : CALL wfs_release(wf_history%past_states(i)%snapshot)
215 10367 : DEALLOCATE (wf_history%past_states(i)%snapshot)
216 : END IF
217 : END DO
218 9252 : DEALLOCATE (wf_history%past_states)
219 : END IF
220 9252 : DEALLOCATE (wf_history)
221 : END IF
222 : END IF
223 28221 : NULLIFY (wf_history)
224 28221 : END SUBROUTINE wfi_release
225 :
226 : ! **************************************************************************************************
227 : !> \brief Clear stored wavefunction snapshots while preserving history settings.
228 : !> \param wf_history the wf_history to clear
229 : ! **************************************************************************************************
230 2354 : SUBROUTINE wfi_clear(wf_history)
231 : TYPE(qs_wf_history_type), POINTER :: wf_history
232 :
233 : INTEGER :: i
234 :
235 2354 : IF (ASSOCIATED(wf_history)) THEN
236 2354 : CPASSERT(wf_history%ref_count > 0)
237 2354 : IF (ASSOCIATED(wf_history%past_states)) THEN
238 12654 : DO i = 1, SIZE(wf_history%past_states)
239 12654 : IF (ASSOCIATED(wf_history%past_states(i)%snapshot)) THEN
240 2004 : CALL wfs_release(wf_history%past_states(i)%snapshot)
241 2004 : DEALLOCATE (wf_history%past_states(i)%snapshot)
242 2004 : NULLIFY (wf_history%past_states(i)%snapshot)
243 : END IF
244 : END DO
245 : END IF
246 2354 : wf_history%snapshot_count = 0
247 2354 : wf_history%last_state_index = 1
248 : END IF
249 :
250 2354 : END SUBROUTINE wfi_clear
251 :
252 : ! **************************************************************************************************
253 : !> \brief returns a snapshot, the first being the latest snapshot
254 : !> \param wf_history the plage where to get the snapshot
255 : !> \param wf_index the index of the snapshot you want
256 : !> \return ...
257 : !> \par History
258 : !> 12.2002 created [fawzi]
259 : !> \author fawzi
260 : ! **************************************************************************************************
261 70109 : FUNCTION wfi_get_snapshot(wf_history, wf_index) RESULT(res)
262 : TYPE(qs_wf_history_type), POINTER :: wf_history
263 : INTEGER, INTENT(in) :: wf_index
264 : TYPE(qs_wf_snapshot_type), POINTER :: res
265 :
266 70109 : NULLIFY (res)
267 :
268 70109 : CPASSERT(ASSOCIATED(wf_history))
269 70109 : CPASSERT(ASSOCIATED(wf_history%past_states))
270 70109 : IF (wf_index > wf_history%memory_depth .OR. wf_index > wf_history%snapshot_count) THEN
271 0 : CPABORT("Requested wavefunction index not available in history")
272 : END IF
273 : res => wf_history%past_states( &
274 : MODULO(wf_history%snapshot_count + 1 - wf_index, &
275 70109 : wf_history%memory_depth) + 1)%snapshot
276 70109 : END FUNCTION wfi_get_snapshot
277 :
278 0 : END MODULE qs_wf_history_types
|