(git:ed6f26b)
Loading...
Searching...
No Matches
pao_main.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 Main module for the PAO method
10!> \author Ole Schuett
11! **************************************************************************************************
13 USE bibliography, ONLY: schuett2018,&
14 cite_reference
15 USE cp_dbcsr_api, ONLY: dbcsr_add,&
20 dbcsr_set,&
28 USE kinds, ONLY: dp
33 USE machine, ONLY: m_walltime
35 USE pao_io, ONLY: pao_read_restart,&
39 USE pao_methods, ONLY: &
44 USE pao_ml, ONLY: pao_ml_init,&
50 USE pao_param, ONLY: pao_calc_ab,&
54 USE pao_types, ONLY: pao_env_type
57#include "./base/base_uses.f90"
58
59 IMPLICIT NONE
60
61 PRIVATE
62
63 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'pao_main'
64
66
67CONTAINS
68
69! **************************************************************************************************
70!> \brief Initialize the PAO environment
71!> \param qs_env ...
72!> \param ls_scf_env ...
73! **************************************************************************************************
74 SUBROUTINE pao_init(qs_env, ls_scf_env)
75 TYPE(qs_environment_type), POINTER :: qs_env
76 TYPE(ls_scf_env_type), TARGET :: ls_scf_env
77
78 CHARACTER(len=*), PARAMETER :: routinen = 'pao_init'
79
80 INTEGER :: handle
81 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
82 TYPE(pao_env_type), POINTER :: pao
83 TYPE(section_vals_type), POINTER :: input
84
85 IF (.NOT. ls_scf_env%do_pao) RETURN
86
87 CALL timeset(routinen, handle)
88 CALL cite_reference(schuett2018)
89 pao => ls_scf_env%pao_env
90 CALL get_qs_env(qs_env=qs_env, input=input, matrix_s=matrix_s)
91
92 ! parse input
93 CALL parse_pao_section(pao, input)
94
95 CALL pao_init_kinds(pao, qs_env)
96
97 ! train machine learning
98 CALL pao_ml_init(pao, qs_env)
99
100 CALL timestop(handle)
101 END SUBROUTINE pao_init
102
103! **************************************************************************************************
104!> \brief Start a PAO optimization run.
105!> \param qs_env ...
106!> \param ls_scf_env ...
107! **************************************************************************************************
108 SUBROUTINE pao_optimization_start(qs_env, ls_scf_env)
109 TYPE(qs_environment_type), POINTER :: qs_env
110 TYPE(ls_scf_env_type), TARGET :: ls_scf_env
111
112 CHARACTER(len=*), PARAMETER :: routinen = 'pao_optimization_start'
113
114 INTEGER :: handle
115 TYPE(ls_mstruct_type), POINTER :: ls_mstruct
116 TYPE(pao_env_type), POINTER :: pao
117 TYPE(section_vals_type), POINTER :: input, section
118
119 IF (.NOT. ls_scf_env%do_pao) RETURN
120
121 CALL timeset(routinen, handle)
122 CALL get_qs_env(qs_env, input=input)
123 pao => ls_scf_env%pao_env
124 ls_mstruct => ls_scf_env%ls_mstruct
125
126 ! reset state
127 pao%step_start_time = m_walltime()
128 pao%istep = 0
129 pao%matrix_P_ready = .false.
130
131 ! ready stuff that does not depend on atom positions
132 IF (.NOT. pao%constants_ready) THEN
133 CALL pao_build_diag_distribution(pao, qs_env)
134 CALL pao_build_orthogonalizer(pao, qs_env)
135 CALL pao_build_selector(pao, qs_env)
136 CALL pao_build_core_hamiltonian(pao, qs_env)
137 pao%constants_ready = .true.
138 END IF
139
140 CALL pao_param_init(pao, qs_env)
141
142 ! ready PAO parameter matrix_X
143 IF (.NOT. pao%matrix_X_ready) THEN
144 CALL pao_build_matrix_x(pao, qs_env)
145 CALL pao_print_atom_info(pao)
146 IF (len_trim(pao%restart_file) > 0) THEN
147 CALL pao_read_restart(pao, qs_env)
148 ELSE IF (SIZE(pao%ml_training_set) > 0) THEN
149 CALL pao_ml_predict(pao, qs_env)
150 ELSE IF (ALLOCATED(pao%models)) THEN
151 CALL pao_model_predict(pao, qs_env)
152 ELSE
153 CALL pao_param_initial_guess(pao, qs_env)
154 END IF
155 pao%matrix_X_ready = .true.
156 ELSE IF (SIZE(pao%ml_training_set) > 0) THEN
157 CALL pao_ml_predict(pao, qs_env)
158 ELSE IF (ALLOCATED(pao%models)) THEN
159 CALL pao_model_predict(pao, qs_env)
160 ELSE
161 IF (pao%iw > 0) WRITE (pao%iw, *) "PAO| reusing matrix_X from previous optimization"
162 END IF
163
164 ! init line-search
165 section => section_vals_get_subs_vals(input, "DFT%LS_SCF%PAO%LINE_SEARCH")
166 CALL linesearch_init(pao%linesearch, section, "PAO|")
167
168 ! create some more matrices
169 CALL dbcsr_copy(pao%matrix_G, pao%matrix_X)
170 CALL dbcsr_set(pao%matrix_G, 0.0_dp)
171
172 CALL dbcsr_create(ls_mstruct%matrix_A, template=pao%matrix_Y)
173 CALL dbcsr_reserve_diag_blocks(ls_mstruct%matrix_A)
174 CALL dbcsr_create(ls_mstruct%matrix_B, template=pao%matrix_Y)
175 CALL dbcsr_reserve_diag_blocks(ls_mstruct%matrix_B)
176
177 ! fill PAO transformation matrices
178 CALL pao_calc_ab(pao, qs_env, ls_scf_env, gradient=.false.)
179
180 CALL timestop(handle)
181 END SUBROUTINE pao_optimization_start
182
183! **************************************************************************************************
184!> \brief Called after the SCF optimization, updates the PAO basis.
185!> \param qs_env ...
186!> \param ls_scf_env ...
187!> \param pao_is_done ...
188! **************************************************************************************************
189 SUBROUTINE pao_update(qs_env, ls_scf_env, pao_is_done)
190 TYPE(qs_environment_type), POINTER :: qs_env
191 TYPE(ls_scf_env_type), TARGET :: ls_scf_env
192 LOGICAL, INTENT(OUT) :: pao_is_done
193
194 CHARACTER(len=*), PARAMETER :: routinen = 'pao_update'
195
196 INTEGER :: handle, icycle
197 LOGICAL :: cycle_converged, do_mixing, should_stop
198 REAL(kind=dp) :: energy, penalty
199 TYPE(dbcsr_type) :: matrix_x_mixing
200 TYPE(ls_mstruct_type), POINTER :: ls_mstruct
201 TYPE(pao_env_type), POINTER :: pao
202
203 IF (.NOT. ls_scf_env%do_pao) THEN
204 pao_is_done = .true.
205 RETURN
206 END IF
207
208 ls_mstruct => ls_scf_env%ls_mstruct
209 pao => ls_scf_env%pao_env
210
211 IF (.NOT. pao%matrix_P_ready) THEN
212 CALL pao_guess_initial_p(pao, qs_env, ls_scf_env)
213 pao%matrix_P_ready = .true.
214 END IF
215
216 IF (pao%max_pao == 0) THEN
217 pao_is_done = .true.
218 RETURN
219 END IF
220
221 IF (pao%need_initial_scf) THEN
222 pao_is_done = .false.
223 pao%need_initial_scf = .false.
224 IF (pao%iw > 0) WRITE (pao%iw, *) "PAO| Performing initial SCF optimization."
225 RETURN
226 END IF
227
228 CALL timeset(routinen, handle)
229
230 ! perform mixing once we are well into the optimization
231 do_mixing = pao%mixing /= 1.0_dp .AND. pao%istep > 1
232 IF (do_mixing) THEN
233 CALL dbcsr_copy(matrix_x_mixing, pao%matrix_X)
234 END IF
235
236 cycle_converged = .false.
237 icycle = 0
238 CALL linesearch_reset(pao%linesearch)
239 CALL pao_opt_init(pao)
240
241 DO WHILE (.true.)
242 pao%istep = pao%istep + 1
243
244 IF (pao%iw > 0) WRITE (pao%iw, "(A,I9,A)") " PAO| ======================= Iteration: ", &
245 pao%istep, " ============================="
246
247 ! calc energy and check trace_PS
248 CALL pao_calc_energy(pao, qs_env, ls_scf_env, energy)
249 CALL pao_check_trace_ps(ls_scf_env)
250
251 IF (pao%linesearch%starts) THEN
252 icycle = icycle + 1
253 ! calc new gradient including penalty terms
254 CALL pao_calc_ab(pao, qs_env, ls_scf_env, gradient=.true., penalty=penalty)
255 CALL pao_check_grad(pao, qs_env, ls_scf_env)
256
257 ! calculate new direction for line-search
258 CALL pao_opt_new_dir(pao, icycle)
259
260 !backup X
261 CALL dbcsr_copy(pao%matrix_X_orig, pao%matrix_X)
262
263 ! print info and convergence test
264 CALL pao_test_convergence(pao, ls_scf_env, energy, cycle_converged)
265 IF (cycle_converged) THEN
266 pao_is_done = icycle < 3
267 IF (pao_is_done .AND. pao%iw > 0) WRITE (pao%iw, *) "PAO| converged after ", pao%istep, " steps :-)"
268 EXIT
269 END IF
270
271 ! if we have reached the maximum number of cycles exit in order
272 ! to restart with a fresh hamiltonian
273 IF (icycle >= pao%max_cycles) THEN
274 IF (pao%iw > 0) WRITE (pao%iw, *) "PAO| CG not yet converged after ", icycle, " cylces."
275 pao_is_done = .false.
276 EXIT
277 END IF
278
279 IF (mod(icycle, pao%write_cycles) == 0) &
280 CALL pao_write_restart(pao, qs_env, energy) ! write an intermediate restart file
281 END IF
282
283 ! check for early abort without convergence?
284 CALL external_control(should_stop, "PAO", start_time=qs_env%start_time, target_time=qs_env%target_time)
285 IF (should_stop .OR. pao%istep >= pao%max_pao) THEN
286 cpwarn("PAO not converged!")
287 pao_is_done = .true.
288 EXIT
289 END IF
290
291 ! perform line-search step
292 CALL linesearch_step(pao%linesearch, energy=energy, slope=pao%norm_G**2)
293
294 IF (pao%linesearch%step_size < 1e-9_dp) cpabort("PAO gradient is wrong.")
295
296 CALL dbcsr_copy(pao%matrix_X, pao%matrix_X_orig) !restore X
297 CALL dbcsr_add(pao%matrix_X, pao%matrix_D, 1.0_dp, pao%linesearch%step_size)
298 END DO
299
300 ! perform mixing of matrix_X
301 IF (do_mixing) THEN
302 CALL dbcsr_add(pao%matrix_X, matrix_x_mixing, pao%mixing, 1.0_dp - pao%mixing)
303 CALL dbcsr_release(matrix_x_mixing)
304 IF (pao%iw > 0) WRITE (pao%iw, *) "PAO| Recalculating energy after mixing."
305 CALL pao_calc_energy(pao, qs_env, ls_scf_env, energy)
306 END IF
307
308 CALL pao_write_restart(pao, qs_env, energy)
309 CALL pao_opt_finalize(pao)
310
311 CALL timestop(handle)
312 END SUBROUTINE pao_update
313
314! **************************************************************************************************
315!> \brief Calculate PAO forces and store density matrix for future ASPC extrapolations
316!> \param qs_env ...
317!> \param ls_scf_env ...
318!> \param pao_is_done ...
319! **************************************************************************************************
320 SUBROUTINE pao_post_scf(qs_env, ls_scf_env, pao_is_done)
321 TYPE(qs_environment_type), POINTER :: qs_env
322 TYPE(ls_scf_env_type), TARGET :: ls_scf_env
323 LOGICAL, INTENT(IN) :: pao_is_done
324
325 CHARACTER(len=*), PARAMETER :: routinen = 'pao_post_scf'
326
327 INTEGER :: handle
328
329 IF (.NOT. ls_scf_env%do_pao) RETURN
330 IF (.NOT. pao_is_done) RETURN
331
332 CALL timeset(routinen, handle)
333
334 ! print out the matrices here before pao_store_P converts them back into matrices in
335 ! terms of the primary basis
336 CALL pao_write_ks_matrix_csr(qs_env, ls_scf_env)
337 CALL pao_write_s_matrix_csr(qs_env, ls_scf_env)
338
339 CALL pao_store_p(qs_env, ls_scf_env)
340 IF (ls_scf_env%calculate_forces) CALL pao_add_forces(qs_env, ls_scf_env)
341
342 CALL timestop(handle)
343 END SUBROUTINE
344
345! **************************************************************************************************
346!> \brief Finish a PAO optimization run.
347!> \param ls_scf_env ...
348! **************************************************************************************************
349 SUBROUTINE pao_optimization_end(ls_scf_env)
350 TYPE(ls_scf_env_type), TARGET :: ls_scf_env
351
352 CHARACTER(len=*), PARAMETER :: routinen = 'pao_optimization_end'
353
354 INTEGER :: handle
355 TYPE(ls_mstruct_type), POINTER :: ls_mstruct
356 TYPE(pao_env_type), POINTER :: pao
357
358 IF (.NOT. ls_scf_env%do_pao) RETURN
359
360 pao => ls_scf_env%pao_env
361 ls_mstruct => ls_scf_env%ls_mstruct
362
363 CALL timeset(routinen, handle)
364
365 CALL pao_param_finalize(pao)
366
367 ! We keep pao%matrix_X for next scf-run, e.g. during MD or GEO-OPT
368 CALL dbcsr_release(pao%matrix_X_orig)
369 CALL dbcsr_release(pao%matrix_G)
370 CALL dbcsr_release(ls_mstruct%matrix_A)
371 CALL dbcsr_release(ls_mstruct%matrix_B)
372
373 CALL linesearch_finalize(pao%linesearch)
374
375 CALL timestop(handle)
376 END SUBROUTINE pao_optimization_end
377
378END MODULE pao_main
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public schuett2018
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
subroutine, public dbcsr_reserve_diag_blocks(matrix)
Reserves all diagonal blocks.
Routines to handle the external control of CP2K.
subroutine, public external_control(should_stop, flag, globenv, target_time, start_time, force_check)
External manipulations during a run : when the <PROJECT_NAME>.EXIT_$runtype command is sent the progr...
Types needed for a linear scaling quickstep SCF run based on the density matrix.
objects that represent the structure of input sections and the data contained in an input section
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
A generic framework to calculate step lengths for 1D line search.
Definition linesearch.F:12
subroutine, public linesearch_finalize(this)
Finzalize line search machinery.
Definition linesearch.F:259
subroutine, public linesearch_init(this, section, label)
Initialize linesearch from given input section.
Definition linesearch.F:195
subroutine, public linesearch_reset(this)
Reset line search to initial state.
Definition linesearch.F:285
subroutine, public linesearch_step(this, energy, slope)
Calculate step length of next line search step.
Definition linesearch.F:299
Machine interface based on Fortran 2003 and POSIX.
Definition machine.F:17
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition machine.F:147
subroutine, public parse_pao_section(pao, input)
Declare the PAO input section.
Definition pao_input.F:69
Routines for reading and writing restart files.
Definition pao_io.F:12
subroutine, public pao_write_restart(pao, qs_env, energy)
Writes restart file.
Definition pao_io.F:391
subroutine, public pao_write_ks_matrix_csr(qs_env, ls_scf_env)
writing the KS matrix (in terms of the PAO basis) in csr format into a file
Definition pao_io.F:562
subroutine, public pao_write_s_matrix_csr(qs_env, ls_scf_env)
writing the overlap matrix (in terms of the PAO basis) in csr format into a file
Definition pao_io.F:637
subroutine, public pao_read_restart(pao, qs_env)
Reads restart file.
Definition pao_io.F:87
Main module for the PAO method.
Definition pao_main.F:12
subroutine, public pao_post_scf(qs_env, ls_scf_env, pao_is_done)
Calculate PAO forces and store density matrix for future ASPC extrapolations.
Definition pao_main.F:321
subroutine, public pao_update(qs_env, ls_scf_env, pao_is_done)
Called after the SCF optimization, updates the PAO basis.
Definition pao_main.F:190
subroutine, public pao_init(qs_env, ls_scf_env)
Initialize the PAO environment.
Definition pao_main.F:75
subroutine, public pao_optimization_end(ls_scf_env)
Finish a PAO optimization run.
Definition pao_main.F:350
subroutine, public pao_optimization_start(qs_env, ls_scf_env)
Start a PAO optimization run.
Definition pao_main.F:109
Methods used by pao_main.F.
Definition pao_methods.F:12
subroutine, public pao_build_orthogonalizer(pao, qs_env)
Constructs matrix_N and its inverse.
subroutine, public pao_build_core_hamiltonian(pao, qs_env)
Creates the matrix_H0 which contains the core hamiltonian.
subroutine, public pao_guess_initial_p(pao, qs_env, ls_scf_env)
Provide an initial guess for the density matrix.
subroutine, public pao_test_convergence(pao, ls_scf_env, new_energy, is_converged)
Test whether the PAO optimization has reached convergence.
subroutine, public pao_add_forces(qs_env, ls_scf_env)
Calculate the forces contributed by PAO.
subroutine, public pao_check_trace_ps(ls_scf_env)
Ensure that the number of electrons is correct.
subroutine, public pao_init_kinds(pao, qs_env)
Initialize qs kinds.
Definition pao_methods.F:97
subroutine, public pao_build_matrix_x(pao, qs_env)
Creates the matrix_X.
subroutine, public pao_check_grad(pao, qs_env, ls_scf_env)
Debugging routine for checking the analytic gradient.
subroutine, public pao_print_atom_info(pao)
Prints a one line summary for each atom.
subroutine, public pao_store_p(qs_env, ls_scf_env)
Stores density matrix as initial guess for next SCF optimization.
subroutine, public pao_build_selector(pao, qs_env)
Build rectangular matrix to converert between primary and PAO basis.
subroutine, public pao_calc_energy(pao, qs_env, ls_scf_env, energy)
Calculate the pao energy.
subroutine, public pao_build_diag_distribution(pao, qs_env)
Creates new DBCSR distribution which spreads diagonal blocks evenly across ranks.
Main module for PAO Machine Learning.
Definition pao_ml.F:12
subroutine, public pao_ml_init(pao, qs_env)
Initializes the learning machinery.
Definition pao_ml.F:85
subroutine, public pao_ml_predict(pao, qs_env)
Fills paomatrix_X based on machine learning predictions.
Definition pao_ml.F:505
Module for equivariant PAO-ML based on PyTorch.
Definition pao_model.F:12
subroutine, public pao_model_predict(pao, qs_env)
Fills paomatrix_X based on machine learning predictions.
Definition pao_model.F:156
Optimizers used by pao_main.F.
subroutine, public pao_opt_init(pao)
Initialize the optimizer.
subroutine, public pao_opt_finalize(pao)
Finalize the optimizer.
subroutine, public pao_opt_new_dir(pao, icycle)
Calculates the new search direction.
Front-End for any PAO parametrization.
Definition pao_param.F:12
subroutine, public pao_param_initial_guess(pao, qs_env)
Fills matrix_X with an initial guess.
Definition pao_param.F:207
subroutine, public pao_param_init(pao, qs_env)
Initialize PAO parametrization.
Definition pao_param.F:109
subroutine, public pao_calc_ab(pao, qs_env, ls_scf_env, gradient, penalty, forces)
Takes current matrix_X and calculates the matrices A and B.
Definition pao_param.F:70
subroutine, public pao_param_finalize(pao)
Finalize PAO parametrization.
Definition pao_param.F:140
Types used by the PAO machinery.
Definition pao_types.F:12
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, ecoul_1c, rho0_s_rs, rho0_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs)
Get the QUICKSTEP environment.