Line data Source code
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 Utility subroutine for qs energy calculation
10 : !> \par History
11 : !> 11.2016 split out from qs_energy_utils
12 : !> \author MK (29.10.2002)
13 : ! **************************************************************************************************
14 : MODULE qs_energy_init
15 : USE cp_control_types, ONLY: dft_control_type
16 : USE cp_dbcsr_api, ONLY: dbcsr_copy,&
17 : dbcsr_p_type,&
18 : dbcsr_set,&
19 : dbcsr_type
20 : USE cp_dbcsr_operations, ONLY: dbcsr_allocate_matrix_set
21 : USE efield_utils, ONLY: calculate_ecore_efield
22 : USE input_constants, ONLY: kg_tnadd_atomic,&
23 : kg_tnadd_embed,&
24 : kg_tnadd_embed_ri,&
25 : kg_tnadd_none
26 : USE input_section_types, ONLY: section_vals_type
27 : USE kg_environment, ONLY: kg_build_neighborlist,&
28 : kg_build_subsets
29 : USE kg_environment_types, ONLY: kg_environment_type
30 : USE kinds, ONLY: dp
31 : USE kpoint_methods, ONLY: kpoint_init_cell_index
32 : USE kpoint_types, ONLY: kpoint_type,&
33 : set_kpoint_info
34 : USE lri_environment_methods, ONLY: build_lri_matrices,&
35 : calculate_lri_integrals
36 : USE lri_environment_types, ONLY: lri_environment_type
37 : USE message_passing, ONLY: mp_para_env_type
38 : USE molecule_types, ONLY: molecule_of_atom,&
39 : molecule_type
40 : USE optimize_embedding_potential, ONLY: given_embed_pot
41 : USE qs_core_energies, ONLY: calculate_ecore_overlap,&
42 : calculate_ecore_self
43 : USE qs_core_hamiltonian, ONLY: build_core_hamiltonian_matrix
44 : USE qs_dftb_dispersion, ONLY: calculate_dftb_dispersion
45 : USE qs_dftb_matrices, ONLY: build_dftb_matrices
46 : USE qs_dispersion_pairpot, ONLY: calculate_dispersion_pairpot
47 : USE qs_dispersion_types, ONLY: qs_dispersion_type
48 : USE qs_energy_types, ONLY: qs_energy_type
49 : USE qs_environment_types, ONLY: get_qs_env,&
50 : qs_environment_type
51 : USE qs_external_density, ONLY: external_read_density
52 : USE qs_external_potential, ONLY: external_c_potential,&
53 : external_e_potential
54 : USE qs_gcp_method, ONLY: calculate_gcp_pairpot
55 : USE qs_gcp_types, ONLY: qs_gcp_type
56 : USE qs_ks_methods, ONLY: qs_ks_allocate_basics
57 : USE qs_ks_types, ONLY: get_ks_env,&
58 : qs_ks_env_type,&
59 : set_ks_env
60 : USE qs_neighbor_list_types, ONLY: neighbor_list_set_p_type
61 : USE qs_neighbor_lists, ONLY: build_qs_neighbor_lists
62 : USE qs_update_s_mstruct, ONLY: qs_env_update_s_mstruct
63 : USE ri_environment_methods, ONLY: build_ri_matrices
64 : USE se_core_core, ONLY: se_core_core_interaction
65 : USE se_core_matrix, ONLY: build_se_core_matrix
66 : USE tblite_interface, ONLY: build_tblite_matrices
67 : USE xtb_matrices, ONLY: build_xtb_matrices
68 : #include "./base/base_uses.f90"
69 :
70 : IMPLICIT NONE
71 :
72 : PRIVATE
73 :
74 : ! *** Global parameters ***
75 :
76 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_energy_init'
77 :
78 : PUBLIC :: qs_energies_init
79 :
80 : CONTAINS
81 :
82 : ! **************************************************************************************************
83 : !> \brief Refactoring of qs_energies_scf. Driver routine for the initial
84 : !> setup and calculations for a qs energy calculation
85 : !> \param qs_env ...
86 : !> \param calc_forces ...
87 : !> \par History
88 : !> 05.2013 created [Florian Schiffmann]
89 : ! **************************************************************************************************
90 :
91 21562 : SUBROUTINE qs_energies_init(qs_env, calc_forces)
92 : TYPE(qs_environment_type), POINTER :: qs_env
93 : LOGICAL, INTENT(IN) :: calc_forces
94 :
95 : INTEGER :: img, ispin, nimg, nspin
96 : LOGICAL :: has_unit_metric, ks_is_complex, &
97 : molecule_only
98 21562 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_s, matrix_w
99 : TYPE(dbcsr_type), POINTER :: matrix
100 : TYPE(dft_control_type), POINTER :: dft_control
101 : TYPE(qs_ks_env_type), POINTER :: ks_env
102 :
103 21562 : NULLIFY (ks_env, matrix_w, matrix_s, dft_control)
104 :
105 21562 : CALL get_qs_env(qs_env, dft_control=dft_control, ks_env=ks_env)
106 21562 : IF (dft_control%qs_control%do_kg) THEN
107 112 : molecule_only = .TRUE.
108 112 : CALL qs_energies_init_kg(qs_env)
109 : ELSE
110 21450 : molecule_only = .FALSE.
111 : END IF
112 21562 : CALL qs_energies_init_hamiltonians(qs_env, calc_forces, molecule_only)
113 21562 : CALL get_ks_env(ks_env, complex_ks=ks_is_complex)
114 21562 : CALL qs_ks_allocate_basics(qs_env, is_complex=ks_is_complex)
115 :
116 : ! if need forces allocate energy weighted density matrices
117 21562 : CALL get_qs_env(qs_env, has_unit_metric=has_unit_metric)
118 21562 : IF (calc_forces .AND. .NOT. has_unit_metric) THEN
119 : CALL get_qs_env(qs_env, &
120 : ks_env=ks_env, &
121 6225 : matrix_s_kp=matrix_s)
122 6225 : nspin = dft_control%nspins
123 6225 : nimg = dft_control%nimages
124 6225 : matrix => matrix_s(1, 1)%matrix
125 6225 : CALL dbcsr_allocate_matrix_set(matrix_w, nspin, nimg)
126 13208 : DO ispin = 1, nspin
127 44773 : DO img = 1, nimg
128 31565 : ALLOCATE (matrix_w(ispin, img)%matrix)
129 31565 : CALL dbcsr_copy(matrix_w(ispin, img)%matrix, matrix, name="W MATRIX")
130 38548 : CALL dbcsr_set(matrix_w(ispin, img)%matrix, 0.0_dp)
131 : END DO
132 : END DO
133 6225 : CALL set_ks_env(ks_env, matrix_w_kp=matrix_w)
134 : END IF
135 :
136 21562 : END SUBROUTINE qs_energies_init
137 :
138 : ! **************************************************************************************************
139 : !> \brief Refactoring of qs_energies_scf. Puts initialization of the Kim-Gordon
140 : !> settings into separate subroutine
141 : !> \param qs_env ...
142 : !> \par History
143 : !> 05.2013 created [Florian Schiffmann]
144 : ! **************************************************************************************************
145 :
146 112 : SUBROUTINE qs_energies_init_kg(qs_env)
147 : TYPE(qs_environment_type), POINTER :: qs_env
148 :
149 : CHARACTER(len=*), PARAMETER :: routineN = 'qs_energies_init_kg'
150 :
151 : INTEGER :: handle, isubset, natom
152 : TYPE(dft_control_type), POINTER :: dft_control
153 : TYPE(kg_environment_type), POINTER :: kg_env
154 112 : TYPE(molecule_type), DIMENSION(:), POINTER :: molecule_set
155 : TYPE(mp_para_env_type), POINTER :: para_env
156 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
157 112 : POINTER :: soo_list, soo_list1
158 :
159 112 : CALL timeset(routineN, handle)
160 :
161 112 : CALL get_qs_env(qs_env, dft_control=dft_control, para_env=para_env)
162 112 : CPASSERT(dft_control%qs_control%do_kg)
163 :
164 112 : kg_env => qs_env%kg_env
165 :
166 : ! get the set of molecules
167 112 : CALL get_qs_env(qs_env=qs_env, molecule_set=molecule_set, natom=natom)
168 112 : kg_env%natom = natom
169 : ! store set of molecules in kg_env
170 112 : kg_env%molecule_set => molecule_set
171 : ! build the (new) full neighborlist
172 112 : CALL kg_build_neighborlist(qs_env, sab_orb=kg_env%sab_orb_full)
173 :
174 112 : IF (.NOT. ALLOCATED(kg_env%atom_to_molecule)) THEN
175 192 : ALLOCATE (kg_env%atom_to_molecule(natom))
176 : ! get the mapping from atoms to molecules
177 64 : CALL molecule_of_atom(molecule_set, atom_to_mol=kg_env%atom_to_molecule)
178 : END IF
179 :
180 192 : SELECT CASE (kg_env%tnadd_method)
181 : CASE (kg_tnadd_embed)
182 : ! allocate the subset list
183 80 : IF (.NOT. ASSOCIATED(kg_env%subset_of_mol)) THEN
184 144 : ALLOCATE (kg_env%subset_of_mol(SIZE(molecule_set)))
185 : END IF
186 : !
187 80 : CALL kg_build_subsets(kg_env, para_env)
188 : !
189 246 : DO isubset = 1, kg_env%nsubsets
190 : ! build the (new) molecular neighborlist of the current subset
191 : CALL kg_build_neighborlist(qs_env, sab_orb=kg_env%subset(isubset)%sab_orb, molecular=.TRUE., &
192 246 : subset_of_mol=kg_env%subset_of_mol, current_subset=isubset)
193 : END DO
194 : CASE (kg_tnadd_embed_ri)
195 : ! should be deleted as soon as atomic grids work
196 : ! allocate the subset list
197 2 : IF (.NOT. ASSOCIATED(kg_env%subset_of_mol)) THEN
198 6 : ALLOCATE (kg_env%subset_of_mol(SIZE(molecule_set)))
199 : END IF
200 : !
201 2 : CALL kg_build_subsets(kg_env, para_env)
202 : !
203 6 : DO isubset = 1, kg_env%nsubsets
204 : ! build the (new) molecular neighborlist of the current subset
205 : CALL kg_build_neighborlist(qs_env, sab_orb=kg_env%subset(isubset)%sab_orb, molecular=.TRUE., &
206 6 : subset_of_mol=kg_env%subset_of_mol, current_subset=isubset)
207 : END DO
208 : !
209 : ! LRI neighborlist
210 2 : NULLIFY (soo_list)
211 2 : CALL kg_build_neighborlist(qs_env, sab_orb=soo_list, molecular=.TRUE.)
212 2 : kg_env%lri_env%soo_list => soo_list
213 2 : CALL calculate_lri_integrals(kg_env%lri_env, qs_env)
214 2 : IF (qs_env%energy_correction) THEN
215 0 : NULLIFY (soo_list1)
216 0 : CALL kg_build_neighborlist(qs_env, sab_orb=soo_list1, molecular=.TRUE.)
217 0 : kg_env%lri_env1%soo_list => soo_list1
218 0 : CALL calculate_lri_integrals(kg_env%lri_env1, qs_env)
219 : END IF
220 :
221 : ! Atomic grids
222 : CASE (kg_tnadd_atomic)
223 : ! build the A-C list for the nonadditive kinetic energy potential
224 22 : CALL kg_build_neighborlist(qs_env, sac_kin=kg_env%sac_kin)
225 : CASE (kg_tnadd_none)
226 : ! nothing to do
227 : CASE DEFAULT
228 112 : CPABORT("KG:TNADD METHOD")
229 : END SELECT
230 :
231 112 : CALL timestop(handle)
232 :
233 112 : END SUBROUTINE qs_energies_init_kg
234 :
235 : ! **************************************************************************************************
236 : !> \brief Refactoring of qs_energies_scf. Moves computation of the different
237 : !> core hamiltonians into separate subroutine
238 : !> \param qs_env QS environment
239 : !> \param calc_forces Calculate forces
240 : !> \param molecule_only restrict neighbor list to molecules
241 : !> \par History
242 : !> 05.2013 created [Florian Schiffmann]
243 : !> 08.2014 Kpoints [JGH]
244 : ! **************************************************************************************************
245 :
246 21562 : SUBROUTINE qs_energies_init_hamiltonians(qs_env, calc_forces, molecule_only)
247 : TYPE(qs_environment_type), POINTER :: qs_env
248 : LOGICAL, INTENT(IN) :: calc_forces
249 : LOGICAL :: molecule_only
250 :
251 : CHARACTER(len=*), PARAMETER :: routineN = 'qs_energies_init_hamiltonians'
252 :
253 : INTEGER :: handle
254 : LOGICAL :: do_kpoints
255 : TYPE(dft_control_type), POINTER :: dft_control
256 : TYPE(kpoint_type), POINTER :: kpoints
257 : TYPE(lri_environment_type), POINTER :: lri_env
258 : TYPE(mp_para_env_type), POINTER :: para_env
259 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
260 21562 : POINTER :: sab_nl, sab_nl_nosym
261 : TYPE(qs_dispersion_type), POINTER :: dispersion_env
262 : TYPE(qs_energy_type), POINTER :: energy
263 : TYPE(qs_gcp_type), POINTER :: gcp_env
264 : TYPE(section_vals_type), POINTER :: input
265 :
266 21562 : CALL timeset(routineN, handle)
267 :
268 : CALL get_qs_env(qs_env, &
269 : input=input, &
270 : dft_control=dft_control, &
271 : para_env=para_env, &
272 : kpoints=kpoints, &
273 21562 : do_kpoints=do_kpoints)
274 :
275 : ! create neighbor lists for standard use in QS
276 : CALL build_qs_neighbor_lists(qs_env, para_env, molecular=molecule_only, &
277 21562 : force_env_section=input)
278 :
279 : ! calculate cell index for k-point calculations
280 21562 : IF (do_kpoints) THEN
281 916 : CALL get_qs_env(qs_env, sab_kp=sab_nl, sab_kp_nosym=sab_nl_nosym)
282 916 : CALL kpoint_init_cell_index(kpoints, sab_nl, para_env, dft_control)
283 916 : CALL set_kpoint_info(kpoints, sab_nl_nosym=sab_nl_nosym)
284 : END IF
285 21562 : IF (dft_control%qs_control%cdft) THEN
286 326 : IF (.NOT. (dft_control%qs_control%cdft_control%external_control)) &
287 292 : dft_control%qs_control%cdft_control%need_pot = .TRUE.
288 326 : IF (ASSOCIATED(dft_control%qs_control%cdft_control%group)) THEN
289 : ! In case CDFT weight function was built beforehand (in mixed force_eval)
290 326 : IF (ASSOCIATED(dft_control%qs_control%cdft_control%group(1)%weight)) &
291 114 : dft_control%qs_control%cdft_control%need_pot = .FALSE.
292 : END IF
293 : END IF
294 :
295 : ! Calculate the overlap and the core Hamiltonian integral matrix
296 21562 : IF (dft_control%qs_control%semi_empirical) THEN
297 : CALL build_se_core_matrix(qs_env=qs_env, para_env=para_env, &
298 4336 : calculate_forces=.FALSE.)
299 4336 : CALL qs_env_update_s_mstruct(qs_env)
300 4336 : CALL se_core_core_interaction(qs_env, para_env, calculate_forces=.FALSE.)
301 4336 : CALL get_qs_env(qs_env=qs_env, dispersion_env=dispersion_env, energy=energy)
302 4336 : CALL calculate_dispersion_pairpot(qs_env, dispersion_env, energy%dispersion, calc_forces)
303 17226 : ELSEIF (dft_control%qs_control%dftb) THEN
304 : CALL build_dftb_matrices(qs_env=qs_env, para_env=para_env, &
305 2098 : calculate_forces=.FALSE.)
306 : CALL calculate_dftb_dispersion(qs_env=qs_env, para_env=para_env, &
307 2098 : calculate_forces=.FALSE.)
308 2098 : CALL qs_env_update_s_mstruct(qs_env)
309 15128 : ELSEIF (dft_control%qs_control%xtb) THEN
310 4616 : IF (dft_control%qs_control%xtb_control%do_tblite) THEN
311 20 : CALL build_tblite_matrices(qs_env=qs_env, calculate_forces=.FALSE.)
312 : ELSE
313 4596 : CALL build_xtb_matrices(qs_env=qs_env, calculate_forces=.FALSE.)
314 : END IF
315 4616 : CALL qs_env_update_s_mstruct(qs_env)
316 : ELSE
317 10512 : CALL build_core_hamiltonian_matrix(qs_env=qs_env, calculate_forces=.FALSE.)
318 10512 : CALL qs_env_update_s_mstruct(qs_env)
319 10512 : CALL calculate_ecore_self(qs_env)
320 10512 : CALL calculate_ecore_efield(qs_env, calculate_forces=.FALSE.)
321 10512 : CALL calculate_ecore_overlap(qs_env, para_env, calculate_forces=.FALSE.)
322 : !swap external_e_potential before external_c_potential, to ensure
323 : !that external potential on grid is loaded before calculating energy of cores
324 10512 : CALL external_e_potential(qs_env)
325 10512 : IF (.NOT. dft_control%qs_control%gapw) THEN
326 9160 : CALL external_c_potential(qs_env, calculate_forces=.FALSE.)
327 : END IF
328 : ! LRIGPW/RIGPW matrices
329 10512 : IF (dft_control%qs_control%lrigpw) THEN
330 58 : CALL get_qs_env(qs_env=qs_env, lri_env=lri_env)
331 58 : CALL build_lri_matrices(lri_env, qs_env)
332 10454 : ELSE IF (dft_control%qs_control%rigpw) THEN
333 0 : CALL get_qs_env(qs_env=qs_env, lri_env=lri_env)
334 0 : CALL build_ri_matrices(lri_env, qs_env, calculate_forces=.FALSE.)
335 : END IF
336 :
337 : ! ZMP addition to read external density
338 10512 : CALL external_read_density(qs_env)
339 :
340 : ! Add possible pair potential dispersion energy - Evaluate first so we can print
341 : ! energy info at the end of the SCF
342 10512 : CALL get_qs_env(qs_env=qs_env, dispersion_env=dispersion_env, energy=energy)
343 10512 : CALL calculate_dispersion_pairpot(qs_env, dispersion_env, energy%dispersion, calc_forces)
344 : ! Add possible pair potential gCP energy - Evaluate first so we can print
345 : ! energy info at the end of the SCF
346 10512 : CALL get_qs_env(qs_env=qs_env, gcp_env=gcp_env, energy=energy)
347 10512 : IF (ASSOCIATED(gcp_env)) THEN
348 10512 : CALL calculate_gcp_pairpot(qs_env, gcp_env, energy%gcp, calc_forces)
349 : END IF
350 :
351 : END IF
352 : ! Embedding potential
353 21562 : IF (dft_control%qs_control%dfet_embedded) THEN
354 2 : dft_control%apply_embed_pot = .TRUE.
355 2 : CALL given_embed_pot(qs_env)
356 : END IF
357 : ! Matrix embedding potential
358 21562 : IF (dft_control%qs_control%dmfet_embedded) THEN
359 0 : dft_control%apply_dmfet_pot = .TRUE.
360 : END IF
361 :
362 21562 : CALL timestop(handle)
363 :
364 21562 : END SUBROUTINE qs_energies_init_hamiltonians
365 :
366 : END MODULE qs_energy_init
|