1!--------------------------------------------------------------------------------------------------!
2!   CP2K: A general program to perform molecular dynamics simulations                              !
3!   Copyright (C) 2000 - 2019  CP2K developers group                                               !
4!--------------------------------------------------------------------------------------------------!
5
6MODULE pao_input
7   USE bibliography,                    ONLY: Berghold2011,&
8                                              Schuett2018,&
9                                              Zhu2016
10   USE cp_log_handling,                 ONLY: cp_get_default_logger,&
11                                              cp_logger_type
12   USE cp_output_handling,              ONLY: add_last_numeric,&
13                                              cp_print_key_section_create,&
14                                              cp_print_key_unit_nr,&
15                                              high_print_level,&
16                                              low_print_level
17   USE input_keyword_types,             ONLY: keyword_create,&
18                                              keyword_release,&
19                                              keyword_type
20   USE input_section_types,             ONLY: section_add_keyword,&
21                                              section_add_subsection,&
22                                              section_create,&
23                                              section_release,&
24                                              section_type,&
25                                              section_vals_get_subs_vals,&
26                                              section_vals_type,&
27                                              section_vals_val_get
28   USE input_val_types,                 ONLY: lchar_t,&
29                                              real_t
30   USE kinds,                           ONLY: dp
31   USE linesearch,                      ONLY: linesearch_create_section
32   USE pao_types,                       ONLY: pao_env_type
33   USE string_utilities,                ONLY: s2a
34#include "./base/base_uses.f90"
35
36   IMPLICIT NONE
37   PRIVATE
38
39   CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'pao_input'
40
41   PUBLIC :: create_pao_section, parse_pao_section, id2str
42
43   INTEGER, PARAMETER, PUBLIC               :: pao_rotinv_param = 101, &
44                                               pao_fock_param = 102, &
45                                               pao_exp_param = 103, &
46                                               pao_gth_param = 104, &
47                                               pao_opt_cg = 301, &
48                                               pao_opt_bfgs = 302, &
49                                               pao_ml_gp = 401, &
50                                               pao_ml_nn = 402, &
51                                               pao_ml_lazy = 403, &
52                                               pao_ml_prior_zero = 501, &
53                                               pao_ml_prior_mean = 502, &
54                                               pao_ml_desc_pot = 601, &
55                                               pao_ml_desc_overlap = 602, &
56                                               pao_ml_desc_r12 = 603
57
58CONTAINS
59
60! **************************************************************************************************
61!> \brief Declare the PAO input section
62!> \param pao ...
63!> \param input ...
64! **************************************************************************************************
65   SUBROUTINE parse_pao_section(pao, input)
66      TYPE(pao_env_type), POINTER                        :: pao
67      TYPE(section_vals_type), POINTER                   :: input
68
69      INTEGER                                            :: i, n_rep, ntrainfiles
70      TYPE(cp_logger_type), POINTER                      :: logger
71      TYPE(section_vals_type), POINTER                   :: pao_section, training_set_section
72
73      pao_section => section_vals_get_subs_vals(input, "DFT%LS_SCF%PAO")
74
75      ! open main logger
76      logger => cp_get_default_logger()
77      pao%iw = cp_print_key_unit_nr(logger, pao_section, "PRINT%RUN_INFO", extension=".paolog")
78      pao%iw_atoms = cp_print_key_unit_nr(logger, pao_section, "PRINT%ATOM_INFO", extension=".paolog")
79      pao%iw_gap = cp_print_key_unit_nr(logger, pao_section, "PRINT%FOCK_GAP", extension=".paolog")
80      pao%iw_fockev = cp_print_key_unit_nr(logger, pao_section, "PRINT%FOCK_EIGENVALUES", extension=".paolog")
81      pao%iw_opt = cp_print_key_unit_nr(logger, pao_section, "PRINT%OPT_INFO", extension=".paolog")
82      pao%iw_mlvar = cp_print_key_unit_nr(logger, pao_section, "PRINT%ML_VARIANCE", extension=".paolog")
83      pao%iw_mldata = cp_print_key_unit_nr(logger, pao_section, "PRINT%ML_TRAINING_DATA", extension=".paolog")
84
85      IF (pao%iw > 0) WRITE (pao%iw, *) "" ! an empty separator line
86
87      ! parse input and print
88
89      CALL section_vals_val_get(pao_section, "EPS_PAO", r_val=pao%eps_pao)
90      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,E10.1)") " PAO|", "EPS_PAO", pao%eps_pao
91
92      CALL section_vals_val_get(pao_section, "MIXING", r_val=pao%mixing)
93      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,E10.1)") " PAO|", "MIXING", pao%mixing
94
95      CALL section_vals_val_get(pao_section, "MAX_PAO", i_val=pao%max_pao)
96      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,I10)") " PAO|", "MAX_PAO", pao%max_pao
97
98      CALL section_vals_val_get(pao_section, "MAX_CYCLES", i_val=pao%max_cycles)
99      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,I10)") " PAO|", "MAX_CYCLES", pao%max_cycles
100
101      CALL section_vals_val_get(pao_section, "PARAMETERIZATION", i_val=pao%parameterization)
102      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,A10)") " PAO|", "PARAMETERIZATION", id2str(pao%parameterization)
103
104      CALL section_vals_val_get(pao_section, "PRECONDITION", l_val=pao%precondition)
105      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,L10)") " PAO|", "PRECONDITION", pao%precondition
106
107      CALL section_vals_val_get(pao_section, "REGULARIZATION", r_val=pao%regularization)
108      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,E10.1)") " PAO|", "REGULARIZATION", pao%regularization
109      IF (pao%regularization < 0.0_dp) CPABORT("PAO: REGULARIZATION < 0")
110
111      CALL section_vals_val_get(input, "DFT%QS%EPS_DEFAULT", r_val=pao%eps_pgf) ! default value
112      CALL section_vals_val_get(pao_section, "EPS_PGF", n_rep_val=n_rep)
113      IF (n_rep /= 0) CALL section_vals_val_get(pao_section, "EPS_PGF", r_val=pao%eps_pgf)
114      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,E10.1)") " PAO|", "EPS_PGF", pao%eps_pgf
115      IF (pao%eps_pgf < 0.0_dp) CPABORT("PAO: EPS_PGF < 0")
116
117      CALL section_vals_val_get(pao_section, "PENALTY_DISTANCE", r_val=pao%penalty_dist)
118      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,E10.1)") " PAO|", "PENALTY_DISTANCE", pao%penalty_dist
119      IF (pao%penalty_dist < 0.0_dp) CPABORT("PAO: PENALTY_DISTANCE < 0")
120
121      CALL section_vals_val_get(pao_section, "PENALTY_STRENGTH", r_val=pao%penalty_strength)
122      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,E10.1)") " PAO|", "PENALTY_STRENGTH", pao%penalty_strength
123      IF (pao%penalty_strength < 0.0_dp) CPABORT("PAO: PENALTY_STRENGTH < 0")
124
125      CALL section_vals_val_get(pao_section, "LINPOT_PRECONDITION_DELTA", r_val=pao%linpot_precon_delta)
126      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,E10.1)") " PAO|", "LINPOT_PRECONDITION_DELTA", pao%linpot_precon_delta
127      IF (pao%linpot_precon_delta < 0.0_dp) CPABORT("PAO: LINPOT_PRECONDITION_DELTA < 0")
128
129      CALL section_vals_val_get(pao_section, "LINPOT_INITGUESS_DELTA", r_val=pao%linpot_init_delta)
130      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,E10.1)") " PAO|", "LINPOT_INITGUESS_DELT", pao%linpot_init_delta
131      IF (pao%linpot_init_delta < 0.0_dp) CPABORT("PAO: LINPOT_INITGUESS_DELTA < 0")
132
133      CALL section_vals_val_get(pao_section, "LINPOT_REGULARIZATION_DELTA", r_val=pao%linpot_regu_delta)
134      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,E10.1)") " PAO|", "LINPOT_REGULARIZATION_DELTA", pao%linpot_regu_delta
135      IF (pao%linpot_regu_delta < 0.0_dp) CPABORT("PAO: LINPOT_REGULARIZATION_DELTA < 0")
136
137      CALL section_vals_val_get(pao_section, "LINPOT_REGULARIZATION_STRENGTH", r_val=pao%linpot_regu_strength)
138      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,E10.1)") " PAO|", "LINPOT_REGULARIZATION_STRENGTH", pao%linpot_regu_strength
139      IF (pao%linpot_regu_strength < 0.0_dp) CPABORT("PAO: LINPOT_REGULARIZATION_STRENGTH < 0")
140
141      CALL section_vals_val_get(pao_section, "OPTIMIZER", i_val=pao%optimizer)
142      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,A10)") " PAO|", "OPTIMIZER", id2str(pao%optimizer)
143
144      CALL section_vals_val_get(pao_section, "CG_INIT_STEPS", i_val=pao%cg_init_steps)
145      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,I10)") " PAO|", "CG_INIT_STEPS", pao%cg_init_steps
146      IF (pao%cg_init_steps < 1) CPABORT("PAO: CG_INIT_STEPS < 1")
147
148      CALL section_vals_val_get(pao_section, "CG_RESET_LIMIT", r_val=pao%cg_reset_limit)
149      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,E10.1)") " PAO|", "CG_RESET_LIMIT", pao%cg_reset_limit
150      IF (pao%cg_reset_limit < 0.0_dp) CPABORT("PAO: CG_RESET_LIMIT < 0")
151
152      CALL section_vals_val_get(pao_section, "CHECK_UNITARY_TOL", r_val=pao%check_unitary_tol)
153      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,E10.1)") " PAO|", "CHECK_UNITARY_TOL", pao%check_unitary_tol
154
155      CALL section_vals_val_get(pao_section, "CHECK_GRADIENT_TOL", r_val=pao%check_grad_tol)
156      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,E10.1)") " PAO|", "CHECK_GRADIENT_TOL", pao%check_grad_tol
157
158      CALL section_vals_val_get(pao_section, "NUM_GRADIENT_ORDER", i_val=pao%num_grad_order)
159      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,I10)") " PAO|", "NUM_GRADIENT_ORDER", pao%num_grad_order
160
161      CALL section_vals_val_get(pao_section, "NUM_GRADIENT_EPS", r_val=pao%num_grad_eps)
162      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,E10.1)") " PAO|", "NUM_GRADIENT_EPS", pao%num_grad_eps
163      IF (pao%num_grad_eps < 0.0_dp) CPABORT("PAO: NUM_GRADIENT_EPS < 0")
164
165      CALL section_vals_val_get(pao_section, "PRINT%RESTART%WRITE_CYCLES", i_val=pao%write_cycles)
166      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,I10)") " PAO|", "PRINT%RESTART%WRITE_CYCLES", pao%write_cycles
167
168      CALL section_vals_val_get(pao_section, "RESTART_FILE", c_val=pao%restart_file)
169      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,A)") " PAO|", "RESTART_FILE ", TRIM(pao%restart_file)
170
171      CALL section_vals_val_get(pao_section, "PREOPT_DM_FILE", c_val=pao%preopt_dm_file)
172      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,A)") " PAO|", "PREOPT_DM_FILE ", TRIM(pao%preopt_dm_file)
173
174      CALL section_vals_val_get(pao_section, "MACHINE_LEARNING%METHOD", i_val=pao%ml_method)
175      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,A10)") " PAO|", "MACHINE_LEARNING%METHOD", id2str(pao%ml_method)
176
177      CALL section_vals_val_get(pao_section, "MACHINE_LEARNING%PRIOR", i_val=pao%ml_prior)
178      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,A10)") " PAO|", "MACHINE_LEARNING%PRIOR", id2str(pao%ml_prior)
179
180      CALL section_vals_val_get(pao_section, "MACHINE_LEARNING%DESCRIPTOR", i_val=pao%ml_descriptor)
181      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,A10)") " PAO|", "MACHINE_LEARNING%DESCRIPTOR", id2str(pao%ml_descriptor)
182
183      CALL section_vals_val_get(pao_section, "MACHINE_LEARNING%TOLERANCE", r_val=pao%ml_tolerance)
184      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,E10.1)") " PAO|", "MACHINE_LEARNING%TOLERANCE", pao%ml_tolerance
185
186      CALL section_vals_val_get(pao_section, "MACHINE_LEARNING%GP_NOISE_VAR", r_val=pao%gp_noise_var)
187      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,E10.1)") " PAO|", "MACHINE_LEARNING%GP_NOISE_VAR", pao%gp_noise_var
188
189      CALL section_vals_val_get(pao_section, "MACHINE_LEARNING%GP_SCALE", r_val=pao%gp_scale)
190      IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,E10.1)") " PAO|", "MACHINE_LEARNING%GP_SCALE", pao%gp_scale
191
192      ! parse MACHINE_LEARNING%TRAINING_SET section
193      training_set_section => section_vals_get_subs_vals(pao_section, "MACHINE_LEARNING%TRAINING_SET")
194      CALL section_vals_val_get(training_set_section, "_DEFAULT_KEYWORD_", n_rep_val=ntrainfiles)
195      ALLOCATE (pao%ml_training_set(ntrainfiles))
196      DO i = 1, ntrainfiles
197         CALL section_vals_val_get(training_set_section, "_DEFAULT_KEYWORD_", &
198                                   i_rep_val=i, c_val=pao%ml_training_set(i)%fn)
199         IF (pao%iw > 0) WRITE (pao%iw, "(A,T40,A,T71,A)") " PAO|", "MACHINE_LEARNING%TRAINING_SET", &
200            TRIM(pao%ml_training_set(i)%fn)
201      ENDDO
202
203      IF (pao%iw > 0) WRITE (pao%iw, *) "" ! an empty separator line
204
205   END SUBROUTINE parse_pao_section
206
207! **************************************************************************************************
208!> \brief Helper routine
209!> \param id ...
210!> \return ...
211! **************************************************************************************************
212   FUNCTION id2str(id) RESULT(s)
213      INTEGER                                            :: id
214      CHARACTER(LEN=10)                                  :: s
215
216      CHARACTER(len=*), PARAMETER :: routineN = 'id2str', routineP = moduleN//':'//routineN
217
218      SELECT CASE (id)
219      CASE (pao_gth_param)
220         s = "GTH"
221      CASE (pao_rotinv_param)
222         s = "ROTINV"
223      CASE (pao_fock_param)
224         s = "FOCK"
225      CASE (pao_exp_param)
226         s = "EXP"
227      CASE (pao_opt_cg)
228         s = "CG"
229      CASE (pao_opt_bfgs)
230         s = "BFGS"
231      CASE (pao_ml_gp)
232         s = "GAUSSIAN_PROCESS"
233      CASE (pao_ml_nn)
234         s = "NEURAL_NETWORK"
235      CASE (pao_ml_lazy)
236         s = "LAZY"
237      CASE (pao_ml_prior_zero)
238         s = "ZERO"
239      CASE (pao_ml_prior_mean)
240         s = "MEAN"
241      CASE (pao_ml_desc_pot)
242         s = "POTENTIAL"
243      CASE (pao_ml_desc_overlap)
244         s = "OVERLAP"
245      CASE (pao_ml_desc_r12)
246         s = "R12"
247      CASE DEFAULT
248         CPABORT("PAO: unknown id")
249      END SELECT
250      s = ADJUSTR(s)
251   END FUNCTION id2str
252
253! **************************************************************************************************
254!> \brief Creates the PAO subsection of the linear scaling section.
255!> \param section ...
256!> \author Ole Schuett
257! **************************************************************************************************
258   SUBROUTINE create_pao_section(section)
259      TYPE(section_type), POINTER                        :: section
260
261      CHARACTER(len=*), PARAMETER :: routineN = 'create_pao_section', &
262         routineP = moduleN//':'//routineN
263
264      TYPE(keyword_type), POINTER                        :: keyword
265      TYPE(section_type), POINTER                        :: printkey, subsection, subsubsection
266
267      NULLIFY (keyword, subsection, subsubsection, printkey)
268
269      CPASSERT(.NOT. ASSOCIATED(section))
270      CALL section_create(section, __LOCATION__, name="PAO", repeats=.FALSE., &
271                          description="Polarized Atomic Orbital Method", &
272                          citations=(/Schuett2018, Berghold2011/))
273
274      ! Convergence Criteria *****************************************************
275      CALL keyword_create(keyword, __LOCATION__, name="EPS_PAO", &
276                          description="Convergence criteria for PAO optimization.", &
277                          default_r_val=1.e-5_dp)
278      CALL section_add_keyword(section, keyword)
279      CALL keyword_release(keyword)
280
281      CALL keyword_create(keyword, __LOCATION__, name="MIXING", &
282                          description="Mixing fraction of new and old optimizied solutions.", &
283                          default_r_val=0.5_dp)
284      CALL section_add_keyword(section, keyword)
285      CALL keyword_release(keyword)
286
287      CALL keyword_create(keyword, __LOCATION__, name="MAX_PAO", &
288                          description="Maximum number of PAO basis optimization steps.", &
289                          default_i_val=1000)
290      CALL section_add_keyword(section, keyword)
291      CALL keyword_release(keyword)
292
293      CALL keyword_create(keyword, __LOCATION__, name="MAX_CYCLES", &
294                          description="Maximum number of PAO line search cycles for a given hamiltonian.", &
295                          default_i_val=1000)
296      CALL section_add_keyword(section, keyword)
297      CALL keyword_release(keyword)
298
299      ! Parametrization **********************************************************
300      CALL keyword_create(keyword, __LOCATION__, name="PARAMETERIZATION", &
301                          description="Parametrization of the mapping between the primary and the PAO basis.", &
302                          enum_c_vals=s2a("ROTINV", "FOCK", "GTH", "EXP"), &
303                          enum_i_vals=(/pao_rotinv_param, pao_fock_param, pao_gth_param, pao_exp_param/), &
304                          enum_desc=s2a("Rotational invariant parametrization (machine learnable)", &
305                                        "Fock matrix parametrization", &
306                                        "Parametrization based on GTH pseudo potentials", &
307                                        "Original matrix exponential parametrization"), &
308                          default_i_val=pao_rotinv_param)
309      CALL section_add_keyword(section, keyword)
310      CALL keyword_release(keyword)
311
312      CALL keyword_create(keyword, __LOCATION__, name="REGULARIZATION", &
313                          description="Strength of regularization term which ensures parameters remain small.", &
314                          default_r_val=0.0_dp)
315      CALL section_add_keyword(section, keyword)
316      CALL keyword_release(keyword)
317
318      CALL keyword_create(keyword, __LOCATION__, name="PENALTY_DISTANCE", &
319                          description="Distance at which approaching eigenvalues are penalized to prevent degeneration.", &
320                          default_r_val=0.1_dp)
321      CALL section_add_keyword(section, keyword)
322      CALL keyword_release(keyword)
323
324      CALL keyword_create(keyword, __LOCATION__, name="PENALTY_STRENGTH", &
325                          description="Strength of the penalty term which prevents degenerate eigenvalues.", &
326                          default_r_val=0.005_dp)
327      CALL section_add_keyword(section, keyword)
328      CALL keyword_release(keyword)
329
330      CALL keyword_create(keyword, __LOCATION__, name="PRECONDITION", &
331                          description="Apply a preconditioner to the parametrization.", &
332                          default_l_val=.FALSE., lone_keyword_l_val=.TRUE.)
333      CALL section_add_keyword(section, keyword)
334      CALL keyword_release(keyword)
335
336      CALL keyword_create(keyword, __LOCATION__, name="EPS_PGF", &
337                          description="Sets precision for potential and descriptor matrix elements. "// &
338                          "Overrides DFT/QS/EPS_DEFAULT value.", type_of_var=real_t)
339      CALL section_add_keyword(section, keyword)
340      CALL keyword_release(keyword)
341
342      ! Preopt  ******************************************************************
343      CALL keyword_create(keyword, __LOCATION__, name="PREOPT_DM_FILE", &
344                          description="Read pre-optimized density matrix from given file.", &
345                          repeats=.FALSE., default_c_val="")
346      CALL section_add_keyword(section, keyword)
347      CALL keyword_release(keyword)
348
349      ! Misc ********************************************************************
350      CALL keyword_create(keyword, __LOCATION__, name="RESTART_FILE", &
351                          description="Reads given files as restart for PAO basis", &
352                          repeats=.FALSE., default_c_val="")
353      CALL section_add_keyword(section, keyword)
354      CALL keyword_release(keyword)
355
356      CALL keyword_create(keyword, __LOCATION__, name="CHECK_GRADIENT_TOL", &
357                          description="Tolerance for check of full analytic gradient against the numeric one."// &
358                          " Negative values mean don't check at all.", &
359                          default_r_val=-1.0_dp)
360      CALL section_add_keyword(section, keyword)
361      CALL keyword_release(keyword)
362
363      CALL keyword_create(keyword, __LOCATION__, name="NUM_GRADIENT_EPS", &
364                          description="Step length used for the numeric derivative when checking the gradient.", &
365                          default_r_val=1e-8_dp)
366      CALL section_add_keyword(section, keyword)
367      CALL keyword_release(keyword)
368
369      CALL keyword_create(keyword, __LOCATION__, name="NUM_GRADIENT_ORDER", &
370                          description="Order of the numeric derivative when checking the gradient. "// &
371                          "Possible values are 2, 4, and 6.", &
372                          default_i_val=2)
373      CALL section_add_keyword(section, keyword)
374      CALL keyword_release(keyword)
375
376      CALL keyword_create(keyword, __LOCATION__, name="CHECK_UNITARY_TOL", &
377                          description="Check if rotation matrix is unitary."// &
378                          " Negative values mean don't check at all.", &
379                          default_r_val=-1.0_dp)
380      CALL section_add_keyword(section, keyword)
381      CALL keyword_release(keyword)
382
383      ! Linpot settings  *********************************************************
384      CALL keyword_create(keyword, __LOCATION__, name="LINPOT_PRECONDITION_DELTA", &
385                          description="Eigenvalue threshold used for preconditioning.", &
386                          default_r_val=0.0_dp)
387      CALL section_add_keyword(section, keyword)
388      CALL keyword_release(keyword)
389
390      CALL keyword_create(keyword, __LOCATION__, name="LINPOT_INITGUESS_DELTA", &
391                          description="Eigenvalue threshold used for calculating initial guess.", &
392                          default_r_val=0.0_dp)
393      CALL section_add_keyword(section, keyword)
394      CALL keyword_release(keyword)
395
396      CALL keyword_create(keyword, __LOCATION__, name="LINPOT_REGULARIZATION_DELTA", &
397                          description="Eigenvalue threshold used for regularization.", &
398                          default_r_val=0.0_dp)
399      CALL section_add_keyword(section, keyword)
400      CALL keyword_release(keyword)
401
402      CALL keyword_create(keyword, __LOCATION__, name="LINPOT_REGULARIZATION_STRENGTH", &
403                          description="Strength of regularization on linpot layer.", &
404                          default_r_val=0.0_dp)
405      CALL section_add_keyword(section, keyword)
406      CALL keyword_release(keyword)
407
408      ! Machine Learning *********************************************************
409      CALL section_create(subsection, __LOCATION__, name="MACHINE_LEARNING", description="Machine learning section")
410
411      CALL keyword_create(keyword, __LOCATION__, name="METHOD", &
412                          description="Machine learning scheme used to predict PAO basis sets.", &
413                          enum_c_vals=s2a("GAUSSIAN_PROCESS", "NEURAL_NETWORK", "LAZY"), &
414                          enum_i_vals=(/pao_ml_gp, pao_ml_nn, pao_ml_lazy/), &
415                          enum_desc=s2a("Gaussian Process", "Neural Network", "Just rely on prior"), &
416                          default_i_val=pao_ml_gp)
417      CALL section_add_keyword(subsection, keyword)
418      CALL keyword_release(keyword)
419
420      CALL keyword_create(keyword, __LOCATION__, name="PRIOR", &
421                          description="Prior used for predictions.", &
422                          enum_c_vals=s2a("ZERO", "MEAN"), &
423                          enum_i_vals=(/pao_ml_prior_zero, pao_ml_prior_mean/), &
424                          enum_desc=s2a("Simply use zero", "Use average of training-set"), &
425                          default_i_val=pao_ml_prior_zero)
426      CALL section_add_keyword(subsection, keyword)
427      CALL keyword_release(keyword)
428
429      CALL keyword_create(keyword, __LOCATION__, name="DESCRIPTOR", &
430                          description="Descriptor used as input for machine learning.", &
431                          enum_c_vals=s2a("POTENTIAL", "OVERLAP", "R12"), &
432                          enum_i_vals=(/pao_ml_desc_pot, pao_ml_desc_overlap, pao_ml_desc_r12/), &
433                          enum_desc=s2a("Eigenvalues of local potential matrix", &
434                                        "Eigenvalues of local overlap matrix", &
435                                        "Distance between two atoms (just for testing)"), &
436                          citations=(/Zhu2016/), &
437                          default_i_val=pao_ml_desc_pot)
438      CALL section_add_keyword(subsection, keyword)
439      CALL keyword_release(keyword)
440
441      CALL keyword_create(keyword, __LOCATION__, name="TOLERANCE", &
442                          description="Maximum variance tolerated when making predictions.", &
443                          default_r_val=1.0E-2_dp)
444      CALL section_add_keyword(subsection, keyword)
445      CALL keyword_release(keyword)
446
447      CALL keyword_create(keyword, __LOCATION__, name="GP_NOISE_VAR", &
448                          description="Variance of noise used for Gaussian Process machine learning.", &
449                          default_r_val=0.1_dp)
450      CALL section_add_keyword(subsection, keyword)
451      CALL keyword_release(keyword)
452
453      CALL keyword_create(keyword, __LOCATION__, name="GP_SCALE", &
454                          description="Length scale used for Gaussian Process machine learning.", &
455                          default_r_val=0.05_dp)
456      CALL section_add_keyword(subsection, keyword)
457      CALL keyword_release(keyword)
458
459      ! special free-text section similar to SUBSYS%COORD
460      CALL section_create(subsubsection, __LOCATION__, name="TRAINING_SET", &
461                          description="Lists PAO-restart file used for training")
462      CALL keyword_create(keyword, __LOCATION__, name="_DEFAULT_KEYWORD_", &
463                          description="One file name per line.", &
464                          repeats=.TRUE., type_of_var=lchar_t)
465      CALL section_add_keyword(subsubsection, keyword)
466      CALL keyword_release(keyword)
467      CALL section_add_subsection(subsection, subsubsection)
468      CALL section_release(subsubsection)
469
470      CALL section_add_subsection(section, subsection)
471      CALL section_release(subsection)
472
473      ! Output *******************************************************************
474      CALL section_create(subsection, __LOCATION__, name="PRINT", &
475                          description="Printkey section", &
476                          n_keywords=0, n_subsections=1, repeats=.TRUE.)
477
478      CALL cp_print_key_section_create(printkey, __LOCATION__, "RUN_INFO", &
479                                       description="Normal output by PAO", &
480                                       print_level=low_print_level, add_last=add_last_numeric, filename="__STD_OUT__")
481      CALL section_add_subsection(subsection, printkey)
482      CALL section_release(printkey)
483
484      CALL cp_print_key_section_create(printkey, __LOCATION__, "ATOM_INFO", &
485                                       description="One line summary for each atom", &
486                                       print_level=high_print_level, add_last=add_last_numeric, filename="__STD_OUT__")
487      CALL section_add_subsection(subsection, printkey)
488      CALL section_release(printkey)
489
490      CALL cp_print_key_section_create(printkey, __LOCATION__, "FOCK_GAP", &
491                                       description="Gap of the fock matrix for each atom", &
492                                       print_level=high_print_level, add_last=add_last_numeric, filename="__STD_OUT__")
493      CALL section_add_subsection(subsection, printkey)
494      CALL section_release(printkey)
495
496      CALL cp_print_key_section_create(printkey, __LOCATION__, "FOCK_EIGENVALUES", &
497                                       description="Eigenvalues of the fock matrix for each atom", &
498                                       print_level=high_print_level, add_last=add_last_numeric, filename="__STD_OUT__")
499      CALL section_add_subsection(subsection, printkey)
500      CALL section_release(printkey)
501
502      CALL cp_print_key_section_create(printkey, __LOCATION__, "ML_VARIANCE", &
503                                       description="Variances of machine learning predictions for each atom", &
504                                       print_level=high_print_level, add_last=add_last_numeric, filename="__STD_OUT__")
505      CALL section_add_subsection(subsection, printkey)
506      CALL section_release(printkey)
507
508      CALL cp_print_key_section_create(printkey, __LOCATION__, "ML_TRAINING_DATA", &
509                                       description="Dumps training data used for machine learning", &
510                                       print_level=high_print_level, add_last=add_last_numeric, filename="__STD_OUT__")
511      CALL section_add_subsection(subsection, printkey)
512      CALL section_release(printkey)
513
514      CALL cp_print_key_section_create(printkey, __LOCATION__, "OPT_INFO", &
515                                       description="Output by the optimizer", &
516                                       print_level=low_print_level, add_last=add_last_numeric, filename="__STD_OUT__")
517      CALL section_add_subsection(subsection, printkey)
518      CALL section_release(printkey)
519
520      CALL cp_print_key_section_create(printkey, __LOCATION__, "RESTART", &
521                                       description="Restart file of PAO basis", &
522                                       print_level=high_print_level, add_last=add_last_numeric, filename="")
523
524      CALL keyword_create(keyword, __LOCATION__, name="BACKUP_COPIES", &
525                          description="Specifies the maximum number of backup copies.", &
526                          usage="BACKUP_COPIES {int}", &
527                          default_i_val=1)
528      CALL section_add_keyword(printkey, keyword)
529      CALL keyword_release(keyword)
530
531      CALL keyword_create(keyword, __LOCATION__, name="WRITE_CYCLES", &
532                          description="Maximum number of PAO line search cycles until a restart is written.", &
533                          default_i_val=100)
534      CALL section_add_keyword(printkey, keyword)
535      CALL keyword_release(keyword)
536
537      CALL section_add_subsection(subsection, printkey)
538      CALL section_release(printkey)
539
540      CALL section_add_subsection(section, subsection)
541      CALL section_release(subsection)
542
543      ! OPT stuff ****************************************************************
544      CALL keyword_create(keyword, __LOCATION__, name="OPTIMIZER", &
545                          description="Optimizer used to find PAO basis.", &
546                          enum_c_vals=s2a("CG", "BFGS"), &
547                          enum_i_vals=(/pao_opt_cg, pao_opt_bfgs/), &
548                          enum_desc=s2a("Conjugate gradient algorithm", &
549                                        "Broyden-Fletcher-Goldfarb-Shanno algorithm"), &
550                          default_i_val=pao_opt_cg)
551      CALL section_add_keyword(section, keyword)
552      CALL keyword_release(keyword)
553
554      CALL keyword_create(keyword, __LOCATION__, name="CG_INIT_STEPS", &
555                          description="Number of steepest descent steps before starting the"// &
556                          " conjugate gradients optimization.", &
557                          default_i_val=2)
558      CALL section_add_keyword(section, keyword)
559      CALL keyword_release(keyword)
560
561      CALL keyword_create(keyword, __LOCATION__, name="CG_RESET_LIMIT", &
562                          description="The CG is reseted if the cosine of the angle between the last "// &
563                          "search direction and the new gradient is larger that the limit.", &
564                          default_r_val=0.1_dp)
565      CALL section_add_keyword(section, keyword)
566      CALL keyword_release(keyword)
567
568      CALL linesearch_create_section(subsection)
569      CALL section_add_subsection(section, subsection)
570
571      CALL section_release(subsection)
572   END SUBROUTINE create_pao_section
573
574END MODULE pao_input
575