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