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 qs_environment methods that use many other modules
10 : !> \par History
11 : !> 09.2002 created [fawzi]
12 : !> - local atom distribution (25.06.2003,MK)
13 : !> \author Fawzi Mohamed
14 : ! *****************************************************************************
15 : MODULE qs_update_s_mstruct
16 : USE cp_control_types, ONLY: dft_control_type
17 : USE cp_ddapc_types, ONLY: cp_ddapc_release
18 : USE cp_ddapc_util, ONLY: cp_ddapc_init
19 : USE input_constants, ONLY: do_ppl_analytic,&
20 : do_ppl_grid,&
21 : kg_tnadd_embed,&
22 : kg_tnadd_embed_ri
23 : USE input_section_types, ONLY: section_vals_get_subs_vals,&
24 : section_vals_type,&
25 : section_vals_val_get
26 : USE kinds, ONLY: default_string_length,&
27 : dp
28 : USE pw_methods, ONLY: pw_transfer
29 : USE pw_types, ONLY: pw_c1d_gs_type,&
30 : pw_r3d_rs_type
31 : USE qs_collocate_density, ONLY: calculate_ppl_grid,&
32 : calculate_rho_core,&
33 : calculate_rho_nlcc
34 : USE qs_environment_types, ONLY: get_qs_env,&
35 : qs_environment_type
36 : USE qs_ks_types, ONLY: get_ks_env,&
37 : qs_ks_did_change,&
38 : qs_ks_env_type,&
39 : set_ks_env
40 : USE qs_rho_methods, ONLY: qs_rho_rebuild
41 : USE qs_rho_types, ONLY: qs_rho_type
42 : USE qs_scf_types, ONLY: scf_env_did_change
43 : USE skala_gpw_functional, ONLY: get_gauxc_section,&
44 : native_skala_gapw_composite_direct_ao,&
45 : native_skala_gapw_composite_reference,&
46 : skala_gapw_representation
47 : USE task_list_methods, ONLY: generate_qs_task_list
48 : USE task_list_types, ONLY: allocate_task_list,&
49 : deallocate_task_list,&
50 : task_list_type
51 : USE xc_input_constants, ONLY: skala_gapw_paw_one_center
52 : #include "./base/base_uses.f90"
53 :
54 : IMPLICIT NONE
55 : PRIVATE
56 :
57 : LOGICAL, PRIVATE, PARAMETER :: debug_this_module = .TRUE.
58 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_update_s_mstruct'
59 :
60 : PUBLIC :: qs_env_update_s_mstruct
61 : !***
62 : CONTAINS
63 :
64 : ! *****************************************************************************
65 : !> \brief updates the s_mstruct to reflect the new overlap structure,
66 : !> and also updates rho_core distribution.
67 : !> Should be called after the atoms have moved and the new overlap
68 : !> has been calculated.
69 : !> \param qs_env the environment to update
70 : !> \par History
71 : !> 07.2002 created [fawzi]
72 : !> \author Fawzi Mohamed
73 : ! **************************************************************************************************
74 28664 : SUBROUTINE qs_env_update_s_mstruct(qs_env)
75 : TYPE(qs_environment_type), POINTER :: qs_env
76 :
77 : CHARACTER(len=*), PARAMETER :: routineN = 'qs_env_update_s_mstruct'
78 :
79 : INTEGER :: handle, nk
80 : LOGICAL :: do_ppl
81 : REAL(KIND=dp) :: wtot
82 28664 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: cw
83 : TYPE(dft_control_type), POINTER :: dft_control
84 : TYPE(pw_c1d_gs_type), POINTER :: rho_core, rho_nlcc_g
85 : TYPE(pw_r3d_rs_type), POINTER :: rho_nlcc, vppl, xcint_weights
86 :
87 28664 : CALL timeset(routineN, handle)
88 :
89 28664 : CPASSERT(ASSOCIATED(qs_env))
90 :
91 28664 : NULLIFY (dft_control)
92 : CALL get_qs_env(qs_env, &
93 28664 : dft_control=dft_control)
94 :
95 : ! *** updates rho core ***
96 28664 : NULLIFY (rho_core)
97 28664 : CALL get_qs_env(qs_env, rho_core=rho_core)
98 28664 : IF (dft_control%qs_control%gapw) THEN
99 2202 : qs_env%qs_charges%total_rho_core_rspace = qs_env%local_rho_set%rhoz_tot
100 : ! Initial CNEO quantum nuclear charge density is a simple Zeff sum.
101 : ! Later it will be calculated from numerical integration during SCF.
102 2202 : qs_env%qs_charges%total_rho1_hard_nuc = qs_env%local_rho_set%rhoz_cneo_tot
103 2202 : IF (dft_control%qs_control%gapw_control%nopaw_as_gpw) THEN
104 284 : CPASSERT(ASSOCIATED(rho_core))
105 : CALL calculate_rho_core(rho_core, &
106 284 : qs_env%qs_charges%total_rho_core_rspace, qs_env, only_nopaw=.TRUE.)
107 : ELSE
108 1918 : IF (ASSOCIATED(rho_core)) THEN
109 0 : CALL rho_core%release()
110 0 : DEALLOCATE (rho_core)
111 : END IF
112 : END IF
113 : ! force analytic ppl calculation
114 2202 : dft_control%qs_control%do_ppl_method = do_ppl_analytic
115 26462 : ELSE IF (dft_control%qs_control%semi_empirical) THEN
116 : !??
117 22104 : ELSE IF (dft_control%qs_control%dftb) THEN
118 : !??
119 18688 : ELSE IF (dft_control%qs_control%xtb) THEN
120 : !??
121 : ELSE
122 10390 : CPASSERT(ASSOCIATED(rho_core))
123 : CALL calculate_rho_core(rho_core, &
124 10390 : qs_env%qs_charges%total_rho_core_rspace, qs_env)
125 : END IF
126 :
127 : ! calculate local pseudopotential on grid
128 28664 : do_ppl = dft_control%qs_control%do_ppl_method == do_ppl_grid
129 28664 : IF (do_ppl) THEN
130 12 : NULLIFY (vppl)
131 12 : CALL get_qs_env(qs_env, vppl=vppl)
132 12 : CPASSERT(ASSOCIATED(vppl))
133 12 : CALL calculate_ppl_grid(vppl, qs_env)
134 : END IF
135 :
136 : ! compute the rho_nlcc
137 28664 : NULLIFY (rho_nlcc, rho_nlcc_g)
138 28664 : CALL get_qs_env(qs_env, rho_nlcc=rho_nlcc, rho_nlcc_g=rho_nlcc_g)
139 28664 : IF (ASSOCIATED(rho_nlcc)) THEN
140 58 : CALL calculate_rho_nlcc(rho_nlcc, qs_env)
141 58 : CALL pw_transfer(rho_nlcc, rho_nlcc_g)
142 : END IF
143 :
144 : ! compute the xcint_weights
145 28664 : IF (dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc) THEN
146 2598 : IF (dft_control%qs_control%gapw_control%accurate_xcint) THEN
147 664 : CALL get_qs_env(qs_env, xcint_weights=xcint_weights, nkind=nk)
148 1992 : ALLOCATE (cw(nk))
149 1952 : cw = 1.0_dp
150 : CALL calculate_rho_core(xcint_weights, wtot, qs_env, &
151 664 : dft_control%qs_control%gapw_control%aw, cw)
152 32624396 : xcint_weights%array = 1.0_dp + xcint_weights%array
153 1328 : DEALLOCATE (cw)
154 : END IF
155 : END IF
156 :
157 : ! allocates and creates the task_list
158 28664 : CALL qs_create_task_list(qs_env)
159 :
160 : ! *** environment for ddapc ***
161 28664 : IF (ASSOCIATED(qs_env%cp_ddapc_env)) THEN
162 138 : CALL cp_ddapc_release(qs_env%cp_ddapc_env)
163 138 : DEALLOCATE (qs_env%cp_ddapc_env)
164 : END IF
165 28664 : CALL cp_ddapc_init(qs_env)
166 :
167 : ! *** tell ks_env ***
168 28664 : CALL qs_ks_did_change(qs_env%ks_env, s_mstruct_changed=.TRUE.)
169 :
170 : ! *** Updates rho structure ***
171 28664 : CALL qs_env_rebuild_rho(qs_env=qs_env)
172 :
173 : ! *** tell scf_env ***
174 28664 : IF (ASSOCIATED(qs_env%scf_env)) THEN
175 19444 : CALL scf_env_did_change(qs_env%scf_env)
176 : END IF
177 :
178 28664 : CALL timestop(handle)
179 :
180 28664 : END SUBROUTINE qs_env_update_s_mstruct
181 :
182 : ! *****************************************************************************
183 : !> \brief ...
184 : !> \param qs_env ...
185 : ! **************************************************************************************************
186 28664 : SUBROUTINE qs_create_task_list(qs_env)
187 : TYPE(qs_environment_type), POINTER :: qs_env
188 :
189 : CHARACTER(len=*), PARAMETER :: routineN = 'qs_create_task_list'
190 :
191 : CHARACTER(LEN=default_string_length) :: basis_type
192 : INTEGER :: handle, isub
193 : LOGICAL :: composite_direct_ao, composite_reference, native_grid_diagnostics, &
194 : paw_one_center, skip_load_balance_distributed, soft_valid
195 : TYPE(dft_control_type), POINTER :: dft_control
196 : TYPE(qs_ks_env_type), POINTER :: ks_env
197 : TYPE(section_vals_type), POINTER :: gauxc_section, input, xc_section
198 : TYPE(task_list_type), POINTER :: task_list
199 :
200 28664 : CALL timeset(routineN, handle)
201 28664 : NULLIFY (ks_env, dft_control, gauxc_section, input, xc_section)
202 28664 : CALL get_qs_env(qs_env, ks_env=ks_env, dft_control=dft_control, input=input)
203 :
204 28664 : soft_valid = (dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc)
205 28664 : xc_section => section_vals_get_subs_vals(input, "DFT%XC")
206 28664 : composite_reference = native_skala_gapw_composite_reference(xc_section)
207 : composite_direct_ao = composite_reference .AND. &
208 28664 : native_skala_gapw_composite_direct_ao(xc_section)
209 28664 : paw_one_center = skala_gapw_representation(xc_section) == skala_gapw_paw_one_center
210 28664 : native_grid_diagnostics = .FALSE.
211 28664 : gauxc_section => get_gauxc_section(xc_section)
212 28664 : IF (ASSOCIATED(gauxc_section)) THEN
213 : CALL section_vals_val_get(gauxc_section, "NATIVE_GRID_DIAGNOSTICS", &
214 190 : l_val=native_grid_diagnostics)
215 : END IF
216 28664 : skip_load_balance_distributed = dft_control%qs_control%skip_load_balance_distributed
217 28664 : IF (.NOT. (dft_control%qs_control%semi_empirical &
218 : .OR. dft_control%qs_control%xtb &
219 : .OR. dft_control%qs_control%dftb)) THEN
220 : ! generate task lists (non-soft)
221 12592 : IF (.NOT. dft_control%qs_control%gapw .OR. composite_direct_ao .OR. &
222 : ((composite_reference .OR. paw_one_center) .AND. native_grid_diagnostics)) THEN
223 10396 : CALL get_ks_env(ks_env, task_list=task_list)
224 10396 : IF (.NOT. ASSOCIATED(task_list)) THEN
225 5004 : CALL allocate_task_list(task_list)
226 5004 : CALL set_ks_env(ks_env, task_list=task_list)
227 : END IF
228 : CALL generate_qs_task_list(ks_env, task_list, basis_type="ORB", &
229 : reorder_rs_grid_ranks=.TRUE., &
230 10396 : skip_load_balance_distributed=skip_load_balance_distributed)
231 : END IF
232 : ! generate the soft task list
233 12592 : IF (dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc) THEN
234 2598 : CALL get_ks_env(ks_env, task_list_soft=task_list)
235 2598 : IF (.NOT. ASSOCIATED(task_list)) THEN
236 1446 : CALL allocate_task_list(task_list)
237 1446 : CALL set_ks_env(ks_env, task_list_soft=task_list)
238 : END IF
239 : CALL generate_qs_task_list(ks_env, task_list, basis_type="ORB_SOFT", &
240 : reorder_rs_grid_ranks=.TRUE., &
241 2598 : skip_load_balance_distributed=skip_load_balance_distributed)
242 : END IF
243 : END IF
244 :
245 28664 : IF (dft_control%qs_control%do_kg) THEN
246 :
247 140 : IF (qs_env%kg_env%tnadd_method == kg_tnadd_embed .OR. &
248 : qs_env%kg_env%tnadd_method == kg_tnadd_embed_ri) THEN
249 :
250 102 : IF (ASSOCIATED(qs_env%kg_env%subset)) THEN
251 324 : DO isub = 1, qs_env%kg_env%nsubsets
252 324 : IF (ASSOCIATED(qs_env%kg_env%subset(isub)%task_list)) THEN
253 64 : CALL deallocate_task_list(qs_env%kg_env%subset(isub)%task_list)
254 : END IF
255 : END DO
256 : ELSE
257 0 : ALLOCATE (qs_env%kg_env%subset(qs_env%kg_env%nsubsets))
258 : END IF
259 :
260 102 : IF (soft_valid) THEN
261 20 : basis_type = "ORB_SOFT"
262 : ELSE
263 82 : basis_type = "ORB"
264 : END IF
265 :
266 324 : DO isub = 1, qs_env%kg_env%nsubsets
267 222 : CALL allocate_task_list(qs_env%kg_env%subset(isub)%task_list)
268 : ! generate the subset task list from the neighborlist
269 : CALL generate_qs_task_list(ks_env, qs_env%kg_env%subset(isub)%task_list, &
270 : basis_type=basis_type, &
271 : reorder_rs_grid_ranks=.FALSE., &
272 : skip_load_balance_distributed=skip_load_balance_distributed, &
273 324 : sab_orb_external=qs_env%kg_env%subset(isub)%sab_orb)
274 : END DO
275 :
276 : END IF
277 :
278 : END IF
279 :
280 28664 : CALL timestop(handle)
281 :
282 28664 : END SUBROUTINE qs_create_task_list
283 :
284 : ! *****************************************************************************
285 : !> \brief rebuilds the rho structure, making sure that everything is allocated
286 : !> and has the right size
287 : !> \param qs_env the environment in which rho should be rebuilt
288 : !> \param rebuild_ao if it is necessary to rebuild rho_ao. Defaults to true.
289 : !> \param rebuild_grids if it in necessary to rebuild rho_r and rho_g.
290 : !> Defaults to false.
291 : !> \par History
292 : !> 10.2002 created [fawzi]
293 : !> \author Fawzi Mohamed
294 : !> \note
295 : !> needs updated pw pools, s_mstruct and h.
296 : !> The use of p to keep the structure of h (needed for the forces)
297 : !> is ugly and should be removed.
298 : !> If necessary rho is created from scratch.
299 : ! **************************************************************************************************
300 28664 : SUBROUTINE qs_env_rebuild_rho(qs_env, rebuild_ao, rebuild_grids)
301 : TYPE(qs_environment_type), POINTER :: qs_env
302 : LOGICAL, INTENT(in), OPTIONAL :: rebuild_ao, rebuild_grids
303 :
304 : CHARACTER(len=*), PARAMETER :: routineN = 'qs_env_rebuild_rho'
305 :
306 : INTEGER :: handle
307 : LOGICAL :: do_admm, gapw_xc
308 : TYPE(dft_control_type), POINTER :: dft_control
309 : TYPE(qs_rho_type), POINTER :: rho, rho_external, rho_xc
310 :
311 28664 : NULLIFY (rho)
312 28664 : CALL timeset(routineN, handle)
313 :
314 : CALL get_qs_env(qs_env, &
315 : dft_control=dft_control, &
316 : rho=rho, &
317 : rho_xc=rho_xc, &
318 28664 : rho_external=rho_external)
319 :
320 28664 : gapw_xc = dft_control%qs_control%gapw_xc
321 28664 : do_admm = dft_control%do_admm
322 : CALL qs_rho_rebuild(rho, qs_env=qs_env, &
323 28664 : rebuild_ao=rebuild_ao, rebuild_grids=rebuild_grids)
324 :
325 28664 : IF (gapw_xc) THEN
326 : CALL qs_rho_rebuild(rho_xc, qs_env=qs_env, &
327 396 : rebuild_ao=rebuild_ao, rebuild_grids=rebuild_grids)
328 : END IF
329 :
330 : ! ZMP rebuilding external density
331 28664 : IF (dft_control%apply_external_density) THEN
332 : CALL qs_rho_rebuild(rho_external, qs_env=qs_env, &
333 0 : rebuild_grids=rebuild_grids)
334 0 : dft_control%read_external_density = .TRUE.
335 : END IF
336 :
337 28664 : CALL timestop(handle)
338 :
339 28664 : END SUBROUTINE qs_env_rebuild_rho
340 :
341 : END MODULE qs_update_s_mstruct
|