(git:e5fdd81)
pao_main.F
Go to the documentation of this file.
1 !--------------------------------------------------------------------------------------------------!
2 ! CP2K: A general program to perform molecular dynamics simulations !
3 ! Copyright 2000-2024 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 ! **************************************************************************************************
12 MODULE pao_main
13  USE bibliography, ONLY: schuett2018,&
14  cite_reference
16  USE dbcsr_api, ONLY: dbcsr_add,&
17  dbcsr_copy,&
18  dbcsr_create,&
19  dbcsr_p_type,&
20  dbcsr_release,&
21  dbcsr_reserve_diag_blocks,&
22  dbcsr_set,&
23  dbcsr_type
24  USE dm_ls_scf_types, ONLY: ls_mstruct_type,&
25  ls_scf_env_type
27  section_vals_type
28  USE kinds, ONLY: dp
29  USE linesearch, ONLY: linesearch_finalize,&
33  USE machine, ONLY: m_walltime
34  USE pao_input, ONLY: parse_pao_section
35  USE pao_io, ONLY: pao_read_restart,&
39  USE pao_methods, ONLY: &
44  USE pao_ml, ONLY: pao_ml_init,&
46  USE pao_optimizer, ONLY: pao_opt_finalize,&
47  pao_opt_init,&
49  USE pao_param, ONLY: pao_calc_ab,&
53  USE pao_types, ONLY: pao_env_type
54  USE qs_environment_types, ONLY: get_qs_env,&
55  qs_environment_type
56 #include "./base/base_uses.f90"
57 
58  IMPLICIT NONE
59 
60  PRIVATE
61 
62  CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'pao_main'
63 
65 
66 CONTAINS
67 
68 ! **************************************************************************************************
69 !> \brief Initialize the PAO environment
70 !> \param qs_env ...
71 !> \param ls_scf_env ...
72 ! **************************************************************************************************
73  SUBROUTINE pao_init(qs_env, ls_scf_env)
74  TYPE(qs_environment_type), POINTER :: qs_env
75  TYPE(ls_scf_env_type), TARGET :: ls_scf_env
76 
77  CHARACTER(len=*), PARAMETER :: routinen = 'pao_init'
78 
79  INTEGER :: handle
80  TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
81  TYPE(pao_env_type), POINTER :: pao
82  TYPE(section_vals_type), POINTER :: input
83 
84  IF (.NOT. ls_scf_env%do_pao) RETURN
85 
86  CALL timeset(routinen, handle)
87  CALL cite_reference(schuett2018)
88  pao => ls_scf_env%pao_env
89  CALL get_qs_env(qs_env=qs_env, input=input, matrix_s=matrix_s)
90 
91  ! parse input
92  CALL parse_pao_section(pao, input)
93 
94  CALL pao_init_kinds(pao, qs_env)
95 
96  ! train machine learning
97  CALL pao_ml_init(pao, qs_env)
98 
99  CALL timestop(handle)
100  END SUBROUTINE pao_init
101 
102 ! **************************************************************************************************
103 !> \brief Start a PAO optimization run.
104 !> \param qs_env ...
105 !> \param ls_scf_env ...
106 ! **************************************************************************************************
107  SUBROUTINE pao_optimization_start(qs_env, ls_scf_env)
108  TYPE(qs_environment_type), POINTER :: qs_env
109  TYPE(ls_scf_env_type), TARGET :: ls_scf_env
110 
111  CHARACTER(len=*), PARAMETER :: routinen = 'pao_optimization_start'
112 
113  INTEGER :: handle
114  TYPE(ls_mstruct_type), POINTER :: ls_mstruct
115  TYPE(pao_env_type), POINTER :: pao
116  TYPE(section_vals_type), POINTER :: input, section
117 
118  IF (.NOT. ls_scf_env%do_pao) RETURN
119 
120  CALL timeset(routinen, handle)
121  CALL get_qs_env(qs_env, input=input)
122  pao => ls_scf_env%pao_env
123  ls_mstruct => ls_scf_env%ls_mstruct
124 
125  ! reset state
126  pao%step_start_time = m_walltime()
127  pao%istep = 0
128  pao%matrix_P_ready = .false.
129 
130  ! ready stuff that does not depend on atom positions
131  IF (.NOT. pao%constants_ready) THEN
132  CALL pao_build_diag_distribution(pao, qs_env)
133  CALL pao_build_orthogonalizer(pao, qs_env)
134  CALL pao_build_selector(pao, qs_env)
135  CALL pao_build_core_hamiltonian(pao, qs_env)
136  pao%constants_ready = .true.
137  END IF
138 
139  CALL pao_param_init(pao, qs_env)
140 
141  ! ready PAO parameter matrix_X
142  IF (.NOT. pao%matrix_X_ready) THEN
143  CALL pao_build_matrix_x(pao, qs_env)
144  CALL pao_print_atom_info(pao)
145  IF (len_trim(pao%restart_file) > 0) THEN
146  CALL pao_read_restart(pao, qs_env)
147  ELSE IF (SIZE(pao%ml_training_set) > 0) THEN
148  CALL pao_ml_predict(pao, qs_env)
149  ELSE
150  CALL pao_param_initial_guess(pao, qs_env)
151  END IF
152  pao%matrix_X_ready = .true.
153  ELSE IF (SIZE(pao%ml_training_set) > 0) THEN
154  CALL pao_ml_predict(pao, qs_env)
155  ELSE
156  IF (pao%iw > 0) WRITE (pao%iw, *) "PAO| reusing matrix_X from previous optimization"
157  END IF
158 
159  ! init line-search
160  section => section_vals_get_subs_vals(input, "DFT%LS_SCF%PAO%LINE_SEARCH")
161  CALL linesearch_init(pao%linesearch, section, "PAO|")
162 
163  ! create some more matrices
164  CALL dbcsr_copy(pao%matrix_G, pao%matrix_X)
165  CALL dbcsr_set(pao%matrix_G, 0.0_dp)
166 
167  CALL dbcsr_create(ls_mstruct%matrix_A, template=pao%matrix_Y)
168  CALL dbcsr_reserve_diag_blocks(ls_mstruct%matrix_A)
169  CALL dbcsr_create(ls_mstruct%matrix_B, template=pao%matrix_Y)
170  CALL dbcsr_reserve_diag_blocks(ls_mstruct%matrix_B)
171 
172  ! fill PAO transformation matrices
173  CALL pao_calc_ab(pao, qs_env, ls_scf_env, gradient=.false.)
174 
175  CALL timestop(handle)
176  END SUBROUTINE pao_optimization_start
177 
178 ! **************************************************************************************************
179 !> \brief Called after the SCF optimization, updates the PAO basis.
180 !> \param qs_env ...
181 !> \param ls_scf_env ...
182 !> \param pao_is_done ...
183 ! **************************************************************************************************
184  SUBROUTINE pao_update(qs_env, ls_scf_env, pao_is_done)
185  TYPE(qs_environment_type), POINTER :: qs_env
186  TYPE(ls_scf_env_type), TARGET :: ls_scf_env
187  LOGICAL, INTENT(OUT) :: pao_is_done
188 
189  CHARACTER(len=*), PARAMETER :: routinen = 'pao_update'
190 
191  INTEGER :: handle, icycle
192  LOGICAL :: cycle_converged, do_mixing, should_stop
193  REAL(kind=dp) :: energy, penalty
194  TYPE(dbcsr_type) :: matrix_x_mixing
195  TYPE(ls_mstruct_type), POINTER :: ls_mstruct
196  TYPE(pao_env_type), POINTER :: pao
197 
198  IF (.NOT. ls_scf_env%do_pao) THEN
199  pao_is_done = .true.
200  RETURN
201  END IF
202 
203  ls_mstruct => ls_scf_env%ls_mstruct
204  pao => ls_scf_env%pao_env
205 
206  IF (.NOT. pao%matrix_P_ready) THEN
207  CALL pao_guess_initial_p(pao, qs_env, ls_scf_env)
208  pao%matrix_P_ready = .true.
209  END IF
210 
211  IF (pao%max_pao == 0) THEN
212  pao_is_done = .true.
213  RETURN
214  END IF
215 
216  IF (pao%need_initial_scf) THEN
217  pao_is_done = .false.
218  pao%need_initial_scf = .false.
219  IF (pao%iw > 0) WRITE (pao%iw, *) "PAO| Performing initial SCF optimization."
220  RETURN
221  END IF
222 
223  CALL timeset(routinen, handle)
224 
225  ! perform mixing once we are well into the optimization
226  do_mixing = pao%mixing /= 1.0_dp .AND. pao%istep > 1
227  IF (do_mixing) THEN
228  CALL dbcsr_copy(matrix_x_mixing, pao%matrix_X)
229  END IF
230 
231  cycle_converged = .false.
232  icycle = 0
233  CALL linesearch_reset(pao%linesearch)
234  CALL pao_opt_init(pao)
235 
236  DO WHILE (.true.)
237  pao%istep = pao%istep + 1
238 
239  IF (pao%iw > 0) WRITE (pao%iw, "(A,I9,A)") " PAO| ======================= Iteration: ", &
240  pao%istep, " ============================="
241 
242  ! calc energy and check trace_PS
243  CALL pao_calc_energy(pao, qs_env, ls_scf_env, energy)
244  CALL pao_check_trace_ps(ls_scf_env)
245 
246  IF (pao%linesearch%starts) THEN
247  icycle = icycle + 1
248  ! calc new gradient including penalty terms
249  CALL pao_calc_ab(pao, qs_env, ls_scf_env, gradient=.true., penalty=penalty)
250  CALL pao_check_grad(pao, qs_env, ls_scf_env)
251 
252  ! calculate new direction for line-search
253  CALL pao_opt_new_dir(pao, icycle)
254 
255  !backup X
256  CALL dbcsr_copy(pao%matrix_X_orig, pao%matrix_X)
257 
258  ! print info and convergence test
259  CALL pao_test_convergence(pao, ls_scf_env, energy, cycle_converged)
260  IF (cycle_converged) THEN
261  pao_is_done = icycle < 3
262  IF (pao_is_done .AND. pao%iw > 0) WRITE (pao%iw, *) "PAO| converged after ", pao%istep, " steps :-)"
263  EXIT
264  END IF
265 
266  ! if we have reached the maximum number of cycles exit in order
267  ! to restart with a fresh hamiltonian
268  IF (icycle >= pao%max_cycles) THEN
269  IF (pao%iw > 0) WRITE (pao%iw, *) "PAO| CG not yet converged after ", icycle, " cylces."
270  pao_is_done = .false.
271  EXIT
272  END IF
273 
274  IF (mod(icycle, pao%write_cycles) == 0) &
275  CALL pao_write_restart(pao, qs_env, energy) ! write an intermediate restart file
276  END IF
277 
278  ! check for early abort without convergence?
279  CALL external_control(should_stop, "PAO", start_time=qs_env%start_time, target_time=qs_env%target_time)
280  IF (should_stop .OR. pao%istep >= pao%max_pao) THEN
281  cpwarn("PAO not converged!")
282  pao_is_done = .true.
283  EXIT
284  END IF
285 
286  ! perform line-search step
287  CALL linesearch_step(pao%linesearch, energy=energy, slope=pao%norm_G**2)
288 
289  IF (pao%linesearch%step_size < 1e-10_dp) cpabort("PAO gradient is wrong.")
290 
291  CALL dbcsr_copy(pao%matrix_X, pao%matrix_X_orig) !restore X
292  CALL dbcsr_add(pao%matrix_X, pao%matrix_D, 1.0_dp, pao%linesearch%step_size)
293  END DO
294 
295  ! perform mixing of matrix_X
296  IF (do_mixing) THEN
297  CALL dbcsr_add(pao%matrix_X, matrix_x_mixing, pao%mixing, 1.0_dp - pao%mixing)
298  CALL dbcsr_release(matrix_x_mixing)
299  IF (pao%iw > 0) WRITE (pao%iw, *) "PAO| Recalculating energy after mixing."
300  CALL pao_calc_energy(pao, qs_env, ls_scf_env, energy)
301  END IF
302 
303  CALL pao_write_restart(pao, qs_env, energy)
304  CALL pao_opt_finalize(pao)
305 
306  CALL timestop(handle)
307  END SUBROUTINE pao_update
308 
309 ! **************************************************************************************************
310 !> \brief Calculate PAO forces and store density matrix for future ASPC extrapolations
311 !> \param qs_env ...
312 !> \param ls_scf_env ...
313 !> \param pao_is_done ...
314 ! **************************************************************************************************
315  SUBROUTINE pao_post_scf(qs_env, ls_scf_env, pao_is_done)
316  TYPE(qs_environment_type), POINTER :: qs_env
317  TYPE(ls_scf_env_type), TARGET :: ls_scf_env
318  LOGICAL, INTENT(IN) :: pao_is_done
319 
320  CHARACTER(len=*), PARAMETER :: routinen = 'pao_post_scf'
321 
322  INTEGER :: handle
323 
324  IF (.NOT. ls_scf_env%do_pao) RETURN
325  IF (.NOT. pao_is_done) RETURN
326 
327  CALL timeset(routinen, handle)
328 
329  ! print out the matrices here before pao_store_P converts them back into matrices in
330  ! terms of the primary basis
331  CALL pao_write_ks_matrix_csr(qs_env, ls_scf_env)
332  CALL pao_write_s_matrix_csr(qs_env, ls_scf_env)
333 
334  CALL pao_store_p(qs_env, ls_scf_env)
335  IF (ls_scf_env%calculate_forces) CALL pao_add_forces(qs_env, ls_scf_env)
336 
337  CALL timestop(handle)
338  END SUBROUTINE
339 
340 ! **************************************************************************************************
341 !> \brief Finish a PAO optimization run.
342 !> \param ls_scf_env ...
343 ! **************************************************************************************************
344  SUBROUTINE pao_optimization_end(ls_scf_env)
345  TYPE(ls_scf_env_type), TARGET :: ls_scf_env
346 
347  CHARACTER(len=*), PARAMETER :: routinen = 'pao_optimization_end'
348 
349  INTEGER :: handle
350  TYPE(ls_mstruct_type), POINTER :: ls_mstruct
351  TYPE(pao_env_type), POINTER :: pao
352 
353  IF (.NOT. ls_scf_env%do_pao) RETURN
354 
355  pao => ls_scf_env%pao_env
356  ls_mstruct => ls_scf_env%ls_mstruct
357 
358  CALL timeset(routinen, handle)
359 
360  CALL pao_param_finalize(pao)
361 
362  ! We keep pao%matrix_X for next scf-run, e.g. during MD or GEO-OPT
363  CALL dbcsr_release(pao%matrix_X_orig)
364  CALL dbcsr_release(pao%matrix_G)
365  CALL dbcsr_release(ls_mstruct%matrix_A)
366  CALL dbcsr_release(ls_mstruct%matrix_B)
367 
368  CALL linesearch_finalize(pao%linesearch)
369 
370  CALL timestop(handle)
371  END SUBROUTINE pao_optimization_end
372 
373 END MODULE pao_main
collects all references to literature in CP2K as new algorithms / method are included from literature...
Definition: bibliography.F:28
integer, save, public schuett2018
Definition: bibliography.F:43
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:123
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:387
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:558
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:633
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:316
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:185
subroutine, public pao_init(qs_env, ls_scf_env)
Initialize the PAO environment.
Definition: pao_main.F:74
subroutine, public pao_optimization_end(ls_scf_env)
Finish a PAO optimization run.
Definition: pao_main.F:345
subroutine, public pao_optimization_start(qs_env, ls_scf_env)
Start a PAO optimization run.
Definition: pao_main.F:108
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.
Definition: pao_methods.F:165
subroutine, public pao_build_core_hamiltonian(pao, qs_env)
Creates the matrix_H0 which contains the core hamiltonian.
Definition: pao_methods.F:401
subroutine, public pao_guess_initial_p(pao, qs_env, ls_scf_env)
Provide an initial guess for the density matrix.
Definition: pao_methods.F:851
subroutine, public pao_test_convergence(pao, ls_scf_env, new_energy, is_converged)
Test whether the PAO optimization has reached convergence.
Definition: pao_methods.F:438
subroutine, public pao_add_forces(qs_env, ls_scf_env)
Calculate the forces contributed by PAO.
Definition: pao_methods.F:954
subroutine, public pao_check_trace_ps(ls_scf_env)
Ensure that the number of electrons is correct.
Definition: pao_methods.F:522
subroutine, public pao_init_kinds(pao, qs_env)
Initialize qs kinds.
Definition: pao_methods.F:92
subroutine, public pao_build_matrix_x(pao, qs_env)
Creates the matrix_X.
Definition: pao_methods.F:357
subroutine, public pao_check_grad(pao, qs_env, ls_scf_env)
Debugging routine for checking the analytic gradient.
Definition: pao_methods.F:679
subroutine, public pao_print_atom_info(pao)
Prints a one line summary for each atom.
Definition: pao_methods.F:135
subroutine, public pao_store_p(qs_env, ls_scf_env)
Stores density matrix as initial guess for next SCF optimization.
Definition: pao_methods.F:804
subroutine, public pao_build_selector(pao, qs_env)
Build rectangular matrix to converert between primary and PAO basis.
Definition: pao_methods.F:249
subroutine, public pao_calc_energy(pao, qs_env, ls_scf_env, energy)
Calculate the pao energy.
Definition: pao_methods.F:479
subroutine, public pao_build_diag_distribution(pao, qs_env)
Creates new DBCSR distribution which spreads diagonal blocks evenly across ranks.
Definition: pao_methods.F:316
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:504
Optimizers used by pao_main.F.
Definition: pao_optimizer.F:12
subroutine, public pao_opt_init(pao)
Initialize the optimizer.
Definition: pao_optimizer.F:37
subroutine, public pao_opt_finalize(pao)
Finalize the optimizer.
Definition: pao_optimizer.F:81
subroutine, public pao_opt_new_dir(pao, icycle)
Calculates the new search direction.
Definition: pao_optimizer.F:99
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_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, 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, rhs)
Get the QUICKSTEP environment.