Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2025 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief Energy correction environment setup and handling
10 : !> \par History
11 : !> 2019.09 created
12 : !> \author JGH
13 : ! **************************************************************************************************
14 : MODULE ec_environment
15 : USE atomic_kind_types, ONLY: atomic_kind_type
16 : USE basis_set_container_types, ONLY: add_basis_set_to_container,&
17 : remove_basis_from_container
18 : USE basis_set_types, ONLY: copy_gto_basis_set,&
19 : create_primitive_basis_set,&
20 : gto_basis_set_type
21 : USE bibliography, ONLY: Niklasson2003,&
22 : Niklasson2014,&
23 : cite_reference
24 : USE cp_control_types, ONLY: dft_control_type
25 : USE cp_log_handling, ONLY: cp_get_default_logger,&
26 : cp_logger_get_default_unit_nr,&
27 : cp_logger_type
28 : USE dm_ls_scf_types, ONLY: ls_scf_env_type
29 : USE ec_env_types, ONLY: energy_correction_type
30 : USE input_constants, ONLY: &
31 : ec_diagonalization, ec_functional_dc, ec_functional_ext, ec_functional_harris, &
32 : ec_matrix_sign, ec_matrix_tc2, ec_matrix_trs4, ec_ot_atomic, ec_ot_diag, ec_ot_gs, &
33 : kg_cholesky, ls_cluster_atomic, ls_cluster_molecular, ls_s_inversion_hotelling, &
34 : ls_s_inversion_none, ls_s_inversion_sign_sqrt, ls_s_preconditioner_atomic, &
35 : ls_s_preconditioner_molecular, ls_s_preconditioner_none, ls_s_sqrt_ns, ls_s_sqrt_proot, &
36 : xc_vdw_fun_nonloc, xc_vdw_fun_pairpot
37 : USE input_cp2k_check, ONLY: xc_functionals_expand
38 : USE input_section_types, ONLY: section_get_ival,&
39 : section_vals_get,&
40 : section_vals_get_subs_vals,&
41 : section_vals_type,&
42 : section_vals_val_get
43 : USE kinds, ONLY: dp
44 : USE message_passing, ONLY: mp_para_env_type
45 : USE molecule_types, ONLY: molecule_of_atom,&
46 : molecule_type
47 : USE orbital_pointers, ONLY: init_orbital_pointers
48 : USE particle_types, ONLY: particle_type
49 : USE qs_dispersion_nonloc, ONLY: qs_dispersion_nonloc_init
50 : USE qs_dispersion_pairpot, ONLY: qs_dispersion_pairpot_init
51 : USE qs_dispersion_types, ONLY: qs_dispersion_type
52 : USE qs_dispersion_utils, ONLY: qs_dispersion_env_set
53 : USE qs_environment_types, ONLY: get_qs_env,&
54 : qs_environment_type
55 : USE qs_interactions, ONLY: init_interaction_radii_orb_basis
56 : USE qs_kind_types, ONLY: get_qs_kind,&
57 : get_qs_kind_set,&
58 : qs_kind_type
59 : USE qs_rho_types, ONLY: qs_rho_type
60 : USE string_utilities, ONLY: uppercase
61 : USE xc, ONLY: xc_uses_kinetic_energy_density,&
62 : xc_uses_norm_drho
63 : USE xc_input_constants, ONLY: xc_deriv_collocate
64 : #include "./base/base_uses.f90"
65 :
66 : IMPLICIT NONE
67 :
68 : PRIVATE
69 :
70 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'ec_environment'
71 :
72 : PUBLIC :: ec_env_create
73 : PUBLIC :: ec_write_input
74 :
75 : CONTAINS
76 :
77 : ! **************************************************************************************************
78 : !> \brief Allocates and intitializes ec_env
79 : !> \param qs_env The QS environment
80 : !> \param ec_env The energy correction environment (the object to create)
81 : !> \param dft_section The DFT section
82 : !> \param ec_section The energy correction input section
83 : !> \par History
84 : !> 2019.09 created
85 : !> \author JGH
86 : ! **************************************************************************************************
87 7366 : SUBROUTINE ec_env_create(qs_env, ec_env, dft_section, ec_section)
88 : TYPE(qs_environment_type), POINTER :: qs_env
89 : TYPE(energy_correction_type), POINTER :: ec_env
90 : TYPE(section_vals_type), POINTER :: dft_section
91 : TYPE(section_vals_type), OPTIONAL, POINTER :: ec_section
92 :
93 7366 : CPASSERT(.NOT. ASSOCIATED(ec_env))
94 191516 : ALLOCATE (ec_env)
95 7366 : CALL init_ec_env(qs_env, ec_env, dft_section, ec_section)
96 :
97 7366 : END SUBROUTINE ec_env_create
98 :
99 : ! **************************************************************************************************
100 : !> \brief Initializes energy correction environment
101 : !> \param qs_env The QS environment
102 : !> \param ec_env The energy correction environment
103 : !> \param dft_section The DFT section
104 : !> \param ec_section The energy correction input section
105 : !> \par History
106 : !> 2019.09 created
107 : !> \author JGH
108 : ! **************************************************************************************************
109 7366 : SUBROUTINE init_ec_env(qs_env, ec_env, dft_section, ec_section)
110 : TYPE(qs_environment_type), POINTER :: qs_env
111 : TYPE(energy_correction_type), POINTER :: ec_env
112 : TYPE(section_vals_type), POINTER :: dft_section
113 : TYPE(section_vals_type), OPTIONAL, POINTER :: ec_section
114 :
115 : CHARACTER(LEN=*), PARAMETER :: routineN = 'init_ec_env'
116 :
117 : INTEGER :: handle, ikind, maxlgto, nkind, unit_nr
118 : LOGICAL :: explicit
119 : REAL(KIND=dp) :: eps_pgf_orb
120 7366 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
121 : TYPE(cp_logger_type), POINTER :: logger
122 : TYPE(dft_control_type), POINTER :: dft_control
123 : TYPE(gto_basis_set_type), POINTER :: basis_set, harris_basis
124 : TYPE(mp_para_env_type), POINTER :: para_env
125 : TYPE(qs_dispersion_type), POINTER :: dispersion_env
126 7366 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
127 : TYPE(qs_kind_type), POINTER :: qs_kind
128 : TYPE(qs_rho_type), POINTER :: rho
129 : TYPE(section_vals_type), POINTER :: ec_hfx_section, nl_section, pp_section, &
130 : section1, section2, xc_fun_section, &
131 : xc_section
132 :
133 7366 : CALL timeset(routineN, handle)
134 :
135 7366 : NULLIFY (atomic_kind_set, dispersion_env, ec_env%ls_env, para_env)
136 7366 : NULLIFY (ec_env%sab_orb, ec_env%sac_ppl, ec_env%sap_ppnl)
137 7366 : NULLIFY (ec_env%matrix_ks, ec_env%matrix_h, ec_env%matrix_s)
138 7366 : NULLIFY (ec_env%matrix_t, ec_env%matrix_p, ec_env%matrix_w)
139 7366 : NULLIFY (ec_env%task_list)
140 7366 : NULLIFY (ec_env%mao_coef)
141 7366 : NULLIFY (ec_env%force)
142 7366 : NULLIFY (ec_env%dispersion_env)
143 7366 : NULLIFY (ec_env%xc_section)
144 7366 : NULLIFY (ec_env%matrix_z)
145 7366 : NULLIFY (ec_env%matrix_hz)
146 7366 : NULLIFY (ec_env%matrix_wz)
147 7366 : NULLIFY (ec_env%z_admm)
148 7366 : NULLIFY (ec_env%p_env)
149 7366 : NULLIFY (ec_env%vxc_rspace)
150 7366 : NULLIFY (ec_env%vtau_rspace)
151 7366 : NULLIFY (ec_env%vadmm_rspace)
152 7366 : NULLIFY (ec_env%rhoout_r, ec_env%rhoz_r)
153 7366 : NULLIFY (ec_env%x_data)
154 7366 : ec_env%should_update = .TRUE.
155 7366 : ec_env%mao = .FALSE.
156 7366 : ec_env%do_ec_admm = .FALSE.
157 7366 : ec_env%do_ec_hfx = .FALSE.
158 7366 : ec_env%reuse_hfx = .FALSE.
159 :
160 7366 : IF (qs_env%energy_correction) THEN
161 :
162 236 : CPASSERT(PRESENT(ec_section))
163 : ! get a useful output_unit
164 236 : logger => cp_get_default_logger()
165 236 : IF (logger%para_env%is_source()) THEN
166 118 : unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
167 : ELSE
168 : unit_nr = -1
169 : END IF
170 :
171 : CALL section_vals_val_get(ec_section, "ALGORITHM", &
172 236 : i_val=ec_env%ks_solver)
173 : CALL section_vals_val_get(ec_section, "ENERGY_FUNCTIONAL", &
174 236 : i_val=ec_env%energy_functional)
175 : CALL section_vals_val_get(ec_section, "FACTORIZATION", &
176 236 : i_val=ec_env%factorization)
177 : CALL section_vals_val_get(ec_section, "OT_INITIAL_GUESS", &
178 236 : i_val=ec_env%ec_initial_guess)
179 : CALL section_vals_val_get(ec_section, "EPS_DEFAULT", &
180 236 : r_val=ec_env%eps_default)
181 : CALL section_vals_val_get(ec_section, "HARRIS_BASIS", &
182 236 : c_val=ec_env%basis)
183 : CALL section_vals_val_get(ec_section, "MAO", &
184 236 : l_val=ec_env%mao)
185 : CALL section_vals_val_get(ec_section, "MAO_MAX_ITER", &
186 236 : i_val=ec_env%mao_max_iter)
187 : CALL section_vals_val_get(ec_section, "MAO_EPS_GRAD", &
188 236 : r_val=ec_env%mao_eps_grad)
189 : CALL section_vals_val_get(ec_section, "MAO_EPS1", &
190 236 : r_val=ec_env%mao_eps1)
191 : CALL section_vals_val_get(ec_section, "MAO_IOLEVEL", &
192 236 : i_val=ec_env%mao_iolevel)
193 : ! Skip EC calculation if ground-state calculation did not converge
194 : CALL section_vals_val_get(ec_section, "SKIP_EC", &
195 236 : l_val=ec_env%skip_ec)
196 : ! Debug output
197 : CALL section_vals_val_get(ec_section, "DEBUG_FORCES", &
198 236 : l_val=ec_env%debug_forces)
199 : CALL section_vals_val_get(ec_section, "DEBUG_STRESS", &
200 236 : l_val=ec_env%debug_stress)
201 : CALL section_vals_val_get(ec_section, "DEBUG_EXTERNAL_METHOD", &
202 236 : l_val=ec_env%debug_external)
203 : ! ADMM
204 236 : CALL section_vals_val_get(ec_section, "ADMM", l_val=ec_env%do_ec_admm)
205 : ! EXTERNAL
206 : CALL section_vals_val_get(ec_section, "EXTERNAL_RESPONSE_FILENAME", &
207 236 : c_val=ec_env%exresp_fn)
208 : CALL section_vals_val_get(ec_section, "EXTERNAL_RESULT_FILENAME", &
209 236 : c_val=ec_env%exresult_fn)
210 : CALL section_vals_val_get(ec_section, "ERROR_ESTIMATION", &
211 236 : l_val=ec_env%do_error)
212 :
213 236 : ec_env%do_skip = .FALSE.
214 :
215 : ! set basis
216 236 : CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set, nkind=nkind)
217 236 : CALL uppercase(ec_env%basis)
218 384 : SELECT CASE (ec_env%basis)
219 : CASE ("ORBITAL")
220 316 : DO ikind = 1, nkind
221 168 : qs_kind => qs_kind_set(ikind)
222 168 : CALL get_qs_kind(qs_kind=qs_kind, basis_set=basis_set, basis_type="ORB")
223 316 : IF (ASSOCIATED(basis_set)) THEN
224 168 : NULLIFY (harris_basis)
225 168 : CALL get_qs_kind(qs_kind=qs_kind, basis_set=harris_basis, basis_type="HARRIS")
226 168 : IF (ASSOCIATED(harris_basis)) THEN
227 6 : CALL remove_basis_from_container(qs_kind%basis_sets, basis_type="HARRIS")
228 : END IF
229 168 : NULLIFY (harris_basis)
230 168 : CALL copy_gto_basis_set(basis_set, harris_basis)
231 168 : CALL add_basis_set_to_container(qs_kind%basis_sets, harris_basis, "HARRIS")
232 : END IF
233 : END DO
234 : CASE ("PRIMITIVE")
235 6 : DO ikind = 1, nkind
236 4 : qs_kind => qs_kind_set(ikind)
237 4 : CALL get_qs_kind(qs_kind=qs_kind, basis_set=basis_set, basis_type="ORB")
238 6 : IF (ASSOCIATED(basis_set)) THEN
239 4 : NULLIFY (harris_basis)
240 4 : CALL get_qs_kind(qs_kind=qs_kind, basis_set=harris_basis, basis_type="HARRIS")
241 4 : IF (ASSOCIATED(harris_basis)) THEN
242 0 : CALL remove_basis_from_container(qs_kind%basis_sets, basis_type="HARRIS")
243 : END IF
244 4 : NULLIFY (harris_basis)
245 4 : CALL create_primitive_basis_set(basis_set, harris_basis)
246 4 : CALL get_qs_env(qs_env, dft_control=dft_control)
247 4 : eps_pgf_orb = dft_control%qs_control%eps_pgf_orb
248 4 : CALL init_interaction_radii_orb_basis(harris_basis, eps_pgf_orb)
249 4 : harris_basis%kind_radius = basis_set%kind_radius
250 4 : CALL add_basis_set_to_container(qs_kind%basis_sets, harris_basis, "HARRIS")
251 : END IF
252 : END DO
253 : CASE ("HARRIS")
254 212 : DO ikind = 1, nkind
255 126 : qs_kind => qs_kind_set(ikind)
256 126 : NULLIFY (harris_basis)
257 126 : CALL get_qs_kind(qs_kind=qs_kind, basis_set=harris_basis, basis_type="HARRIS")
258 212 : IF (.NOT. ASSOCIATED(harris_basis)) THEN
259 0 : CPWARN("Harris Basis not defined for all types of atoms.")
260 : END IF
261 : END DO
262 : CASE DEFAULT
263 236 : CPABORT("Unknown basis set for energy correction (Harris functional)")
264 : END SELECT
265 : !
266 236 : CALL get_qs_kind_set(qs_kind_set, maxlgto=maxlgto, basis_type="HARRIS")
267 236 : CALL init_orbital_pointers(maxlgto + 1)
268 : !
269 236 : CALL uppercase(ec_env%basis)
270 :
271 : ! Basis may only differ from ground-state if explicitly added
272 236 : ec_env%basis_inconsistent = .FALSE.
273 236 : IF (ec_env%basis == "HARRIS") THEN
274 212 : DO ikind = 1, nkind
275 126 : qs_kind => qs_kind_set(ikind)
276 : ! Basis sets of ground-state
277 126 : CALL get_qs_kind(qs_kind=qs_kind, basis_set=basis_set, basis_type="ORB")
278 : ! Basis sets of energy correction
279 126 : CALL get_qs_kind(qs_kind=qs_kind, basis_set=harris_basis, basis_type="HARRIS")
280 :
281 212 : IF (basis_set%name .NE. harris_basis%name) THEN
282 64 : ec_env%basis_inconsistent = .TRUE.
283 : END IF
284 : END DO
285 : END IF
286 :
287 : !Density-corrected DFT must be performed with the same basis as ground-state
288 236 : IF (ec_env%energy_functional == ec_functional_dc .AND. ec_env%basis_inconsistent) THEN
289 : CALL cp_abort(__LOCATION__, &
290 : "DC-DFT: Correction and ground state need to use the same basis. "// &
291 0 : "Checked by comparing basis set names only.")
292 : END IF
293 236 : IF (ec_env%energy_functional == ec_functional_ext .AND. ec_env%basis_inconsistent) THEN
294 : CALL cp_abort(__LOCATION__, &
295 : "Exteranl Energy: Correction and ground state need to use the same basis. "// &
296 0 : "Checked by comparing basis set names only.")
297 : END IF
298 : !
299 : ! set functional
300 382 : SELECT CASE (ec_env%energy_functional)
301 : CASE (ec_functional_harris)
302 146 : ec_env%ec_name = "Harris"
303 : CASE (ec_functional_dc)
304 86 : ec_env%ec_name = "DC-DFT"
305 : CASE (ec_functional_ext)
306 4 : ec_env%ec_name = "External Energy"
307 : CASE DEFAULT
308 236 : CPABORT("unknown energy correction")
309 : END SELECT
310 : ! select the XC section
311 236 : NULLIFY (xc_section)
312 236 : xc_section => section_vals_get_subs_vals(dft_section, "XC")
313 236 : section1 => section_vals_get_subs_vals(ec_section, "XC")
314 236 : section2 => section_vals_get_subs_vals(ec_section, "XC%XC_FUNCTIONAL")
315 236 : CALL section_vals_get(section2, explicit=explicit)
316 236 : IF (explicit) THEN
317 232 : CALL xc_functionals_expand(section2, section1)
318 232 : ec_env%xc_section => section1
319 : ELSE
320 4 : ec_env%xc_section => xc_section
321 : END IF
322 : ! Check whether energy correction requires the kinetic energy density and rebuild rho if necessary
323 236 : CALL get_qs_env(qs_env, dft_control=dft_control, rho=rho)
324 236 : xc_fun_section => section_vals_get_subs_vals(ec_env%xc_section, "XC_FUNCTIONAL")
325 : dft_control%use_kinetic_energy_density = dft_control%use_kinetic_energy_density .OR. &
326 236 : xc_uses_kinetic_energy_density(xc_fun_section, dft_control%lsd)
327 : ! Same for density gradient
328 : dft_control%drho_by_collocation = dft_control%drho_by_collocation .OR. &
329 : (xc_uses_norm_drho(xc_fun_section, dft_control%lsd) .AND. &
330 236 : (section_get_ival(xc_section, "XC_GRID%XC_DERIV") == xc_deriv_collocate))
331 : ! dispersion
332 1180 : ALLOCATE (dispersion_env)
333 : NULLIFY (xc_section)
334 236 : xc_section => ec_env%xc_section
335 236 : CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, para_env=para_env)
336 236 : CALL qs_dispersion_env_set(dispersion_env, xc_section)
337 236 : IF (dispersion_env%type == xc_vdw_fun_pairpot) THEN
338 0 : NULLIFY (pp_section)
339 0 : pp_section => section_vals_get_subs_vals(xc_section, "VDW_POTENTIAL%PAIR_POTENTIAL")
340 0 : CALL qs_dispersion_pairpot_init(atomic_kind_set, qs_kind_set, dispersion_env, pp_section, para_env)
341 236 : ELSE IF (dispersion_env%type == xc_vdw_fun_nonloc) THEN
342 0 : CPABORT("nl-vdW functionals not available for EC calculations")
343 0 : NULLIFY (nl_section)
344 0 : nl_section => section_vals_get_subs_vals(xc_section, "VDW_POTENTIAL%NON_LOCAL")
345 0 : CALL qs_dispersion_nonloc_init(dispersion_env, para_env)
346 : END IF
347 236 : ec_env%dispersion_env => dispersion_env
348 :
349 : ! Check if hybrid functional are used
350 236 : ec_hfx_section => section_vals_get_subs_vals(ec_section, "XC%HF")
351 236 : CALL section_vals_get(ec_hfx_section, explicit=ec_env%do_ec_hfx)
352 :
353 : ! Initialize Harris LS solver environment
354 236 : ec_env%use_ls_solver = .FALSE.
355 : ec_env%use_ls_solver = (ec_env%ks_solver .EQ. ec_matrix_sign) &
356 : .OR. (ec_env%ks_solver .EQ. ec_matrix_trs4) &
357 236 : .OR. (ec_env%ks_solver .EQ. ec_matrix_tc2)
358 :
359 236 : IF (ec_env%use_ls_solver) THEN
360 22 : CALL ec_ls_create(qs_env, ec_env)
361 : END IF
362 :
363 : END IF
364 :
365 7366 : CALL timestop(handle)
366 :
367 7366 : END SUBROUTINE init_ec_env
368 :
369 : ! **************************************************************************************************
370 : !> \brief Initializes linear scaling environment for LS based solver of
371 : !> Harris energy functional and parses input section
372 : !> \param qs_env ...
373 : !> \param ec_env ...
374 : !> \par History
375 : !> 2020.10 created [Fabian Belleflamme]
376 : !> \author Fabian Belleflamme
377 : ! **************************************************************************************************
378 22 : SUBROUTINE ec_ls_create(qs_env, ec_env)
379 : TYPE(qs_environment_type), POINTER :: qs_env
380 : TYPE(energy_correction_type), POINTER :: ec_env
381 :
382 : CHARACTER(LEN=*), PARAMETER :: routineN = 'ec_ls_create'
383 :
384 : INTEGER :: handle
385 : REAL(KIND=dp) :: mu
386 : TYPE(dft_control_type), POINTER :: dft_control
387 : TYPE(ls_scf_env_type), POINTER :: ls_env
388 22 : TYPE(molecule_type), DIMENSION(:), POINTER :: molecule_set
389 22 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
390 : TYPE(section_vals_type), POINTER :: ec_section, input
391 :
392 22 : CALL timeset(routineN, handle)
393 :
394 858 : ALLOCATE (ec_env%ls_env)
395 22 : ls_env => ec_env%ls_env
396 :
397 22 : NULLIFY (dft_control, input, ls_env%para_env)
398 :
399 : CALL get_qs_env(qs_env, &
400 : dft_control=dft_control, &
401 : input=input, &
402 : molecule_set=molecule_set, &
403 : particle_set=particle_set, &
404 : para_env=ls_env%para_env, &
405 22 : nelectron_spin=ls_env%nelectron_spin)
406 :
407 : ! copy some basic stuff
408 22 : ls_env%nspins = dft_control%nspins
409 22 : ls_env%natoms = SIZE(particle_set, 1)
410 22 : CALL ls_env%para_env%retain()
411 :
412 : ! initialize block to group to defined molecules
413 66 : ALLOCATE (ls_env%ls_mstruct%atom_to_molecule(ls_env%natoms))
414 22 : CALL molecule_of_atom(molecule_set, atom_to_mol=ls_env%ls_mstruct%atom_to_molecule)
415 :
416 22 : ls_env%do_transport = .FALSE.
417 22 : ls_env%do_pao = .FALSE.
418 22 : ls_env%ls_mstruct%do_pao = ls_env%do_pao
419 22 : ls_env%do_pexsi = .FALSE.
420 22 : ls_env%has_unit_metric = .FALSE.
421 :
422 22 : ec_section => section_vals_get_subs_vals(input, "DFT%ENERGY_CORRECTION")
423 22 : CALL section_vals_val_get(ec_section, "EPS_FILTER", r_val=ls_env%eps_filter)
424 22 : CALL section_vals_val_get(ec_section, "MU", r_val=mu)
425 22 : CALL section_vals_val_get(ec_section, "FIXED_MU", l_val=ls_env%fixed_mu)
426 66 : ls_env%mu_spin = mu
427 22 : CALL section_vals_val_get(ec_section, "S_PRECONDITIONER", i_val=ls_env%s_preconditioner_type)
428 22 : CALL section_vals_val_get(ec_section, "MATRIX_CLUSTER_TYPE", i_val=ls_env%ls_mstruct%cluster_type)
429 22 : CALL section_vals_val_get(ec_section, "S_INVERSION", i_val=ls_env%s_inversion_type)
430 22 : CALL section_vals_val_get(ec_section, "CHECK_S_INV", l_val=ls_env%check_s_inv)
431 22 : CALL section_vals_val_get(ec_section, "REPORT_ALL_SPARSITIES", l_val=ls_env%report_all_sparsities)
432 22 : CALL section_vals_val_get(ec_section, "SIGN_METHOD", i_val=ls_env%sign_method)
433 22 : CALL section_vals_val_get(ec_section, "SIGN_ORDER", i_val=ls_env%sign_order)
434 22 : CALL section_vals_val_get(ec_section, "DYNAMIC_THRESHOLD", l_val=ls_env%dynamic_threshold)
435 22 : CALL section_vals_val_get(ec_section, "NON_MONOTONIC", l_val=ls_env%non_monotonic)
436 22 : CALL section_vals_val_get(ec_section, "S_SQRT_METHOD", i_val=ls_env%s_sqrt_method)
437 22 : CALL section_vals_val_get(ec_section, "S_SQRT_ORDER", i_val=ls_env%s_sqrt_order)
438 22 : CALL section_vals_val_get(ec_section, "EPS_LANCZOS", r_val=ls_env%eps_lanczos)
439 22 : CALL section_vals_val_get(ec_section, "MAX_ITER_LANCZOS", i_val=ls_env%max_iter_lanczos)
440 :
441 24 : SELECT CASE (ec_env%ks_solver)
442 : CASE (ec_matrix_sign)
443 : ! S inverse required for Sign matrix algorithm,
444 : ! calculated either by Hotelling or multiplying S matrix sqrt inv
445 24 : SELECT CASE (ls_env%s_inversion_type)
446 : CASE (ls_s_inversion_sign_sqrt)
447 2 : ls_env%needs_s_inv = .TRUE.
448 2 : ls_env%use_s_sqrt = .TRUE.
449 : CASE (ls_s_inversion_hotelling)
450 0 : ls_env%needs_s_inv = .TRUE.
451 0 : ls_env%use_s_sqrt = .FALSE.
452 : CASE (ls_s_inversion_none)
453 0 : ls_env%needs_s_inv = .FALSE.
454 0 : ls_env%use_s_sqrt = .FALSE.
455 : CASE DEFAULT
456 2 : CPABORT("")
457 : END SELECT
458 : CASE (ec_matrix_trs4, ec_matrix_tc2)
459 20 : ls_env%needs_s_inv = .FALSE.
460 20 : ls_env%use_s_sqrt = .TRUE.
461 : CASE DEFAULT
462 22 : CPABORT("")
463 : END SELECT
464 :
465 22 : SELECT CASE (ls_env%s_preconditioner_type)
466 : CASE (ls_s_preconditioner_none)
467 0 : ls_env%has_s_preconditioner = .FALSE.
468 : CASE DEFAULT
469 22 : ls_env%has_s_preconditioner = .TRUE.
470 : END SELECT
471 :
472 : ! buffer for the history of matrices, not needed here
473 22 : ls_env%extrapolation_order = 0
474 22 : ls_env%scf_history%nstore = 0
475 22 : ls_env%scf_history%istore = 0
476 44 : ALLOCATE (ls_env%scf_history%matrix(ls_env%nspins, ls_env%scf_history%nstore))
477 :
478 22 : NULLIFY (ls_env%mixing_store)
479 :
480 22 : CALL timestop(handle)
481 :
482 44 : END SUBROUTINE ec_ls_create
483 :
484 : ! **************************************************************************************************
485 : !> \brief Print out the energy correction input section
486 : !>
487 : !> \param ec_env ...
488 : !> \par History
489 : !> 2020.10 created [Fabian Belleflamme]
490 : !> \author Fabian Belleflamme
491 : ! **************************************************************************************************
492 236 : SUBROUTINE ec_write_input(ec_env)
493 : TYPE(energy_correction_type), POINTER :: ec_env
494 :
495 : CHARACTER(LEN=*), PARAMETER :: routineN = 'ec_write_input'
496 :
497 : INTEGER :: handle, unit_nr
498 : TYPE(cp_logger_type), POINTER :: logger
499 : TYPE(ls_scf_env_type), POINTER :: ls_env
500 :
501 236 : CALL timeset(routineN, handle)
502 :
503 236 : logger => cp_get_default_logger()
504 236 : IF (logger%para_env%is_source()) THEN
505 118 : unit_nr = cp_logger_get_default_unit_nr(logger, local=.TRUE.)
506 : ELSE
507 : unit_nr = -1
508 : END IF
509 :
510 118 : IF (unit_nr > 0) THEN
511 :
512 : WRITE (unit_nr, '(T2,A)') &
513 118 : "!"//REPEAT("-", 29)//" Energy Correction "//REPEAT("-", 29)//"!"
514 :
515 : ! Type of energy correction
516 191 : SELECT CASE (ec_env%energy_functional)
517 : CASE (ec_functional_harris)
518 73 : WRITE (unit_nr, '(T2,A,T61,A20)') "Energy Correction: ", "HARRIS FUNCTIONAL"
519 : CASE (ec_functional_dc)
520 43 : WRITE (unit_nr, '(T2,A,T61,A20)') "Energy Correction: ", "DC-DFT"
521 : CASE (ec_functional_ext)
522 118 : WRITE (unit_nr, '(T2,A,T61,A20)') "Energy Correction: ", "External"
523 : END SELECT
524 118 : WRITE (unit_nr, '()')
525 :
526 : ! Energy correction parameters
527 118 : WRITE (unit_nr, '(T2,A,T61,E20.3)') "eps_default:", ec_env%eps_default
528 :
529 118 : CALL uppercase(ec_env%basis)
530 192 : SELECT CASE (ec_env%basis)
531 : CASE ("ORBITAL")
532 74 : WRITE (unit_nr, '(T2,A,T61,A20)') "EC basis: ", "ORBITAL"
533 : CASE ("PRIMITIVE")
534 1 : WRITE (unit_nr, '(T2,A,T61,A20)') "EC basis: ", "PRIMITIVE"
535 : CASE ("HARRIS")
536 118 : WRITE (unit_nr, '(T2,A,T61,A20)') "EC Basis: ", "HARRIS"
537 : END SELECT
538 :
539 : ! Info how HFX in energy correction is treated
540 118 : IF (ec_env%do_ec_hfx) THEN
541 :
542 8 : WRITE (unit_nr, '(T2,A,T61,L20)') "DC-DFT with HFX", ec_env%do_ec_hfx
543 8 : WRITE (unit_nr, '(T2,A,T61,L20)') "Reuse HFX integrals", ec_env%reuse_hfx
544 8 : WRITE (unit_nr, '(T2,A,T61,L20)') "DC-DFT HFX with ADMM", ec_env%do_ec_admm
545 :
546 : END IF ! ec_env%do_ec_hfx
547 :
548 : ! Parameters for Harris functional solver
549 118 : IF (ec_env%energy_functional == ec_functional_harris) THEN
550 :
551 : ! Algorithm
552 133 : SELECT CASE (ec_env%ks_solver)
553 : CASE (ec_diagonalization)
554 60 : WRITE (unit_nr, '(T2,A,T61,A20)') "Algorithm: ", "DIAGONALIZATION"
555 : CASE (ec_ot_diag)
556 2 : WRITE (unit_nr, '(T2,A,T61,A20)') "Algorithm: ", "OT DIAGONALIZATION"
557 : CASE (ec_matrix_sign)
558 1 : WRITE (unit_nr, '(T2,A,T61,A20)') "Algorithm: ", "MATRIX_SIGN"
559 : CASE (ec_matrix_trs4)
560 9 : WRITE (unit_nr, '(T2,A,T61,A20)') "Algorithm: ", "TRS4"
561 9 : CALL cite_reference(Niklasson2003)
562 : CASE (ec_matrix_tc2)
563 1 : WRITE (unit_nr, '(T2,A,T61,A20)') "Algorithm: ", "TC2"
564 74 : CALL cite_reference(Niklasson2014)
565 : END SELECT
566 73 : WRITE (unit_nr, '()')
567 :
568 : ! MAO
569 73 : IF (ec_env%mao) THEN
570 2 : WRITE (unit_nr, '(T2,A,T61,L20)') "MAO:", ec_env%mao
571 2 : WRITE (unit_nr, '(T2,A,T61,L20)') "MAO_IOLEVEL:", ec_env%mao_iolevel
572 2 : WRITE (unit_nr, '(T2,A,T61,I20)') "MAO_MAX_ITER:", ec_env%mao_max_iter
573 2 : WRITE (unit_nr, '(T2,A,T61,E20.3)') "MAO_EPS_GRAD:", ec_env%mao_eps_grad
574 2 : WRITE (unit_nr, '(T2,A,T61,E20.3)') "MAO_EPS1:", ec_env%mao_eps1
575 2 : WRITE (unit_nr, '()')
576 : END IF
577 :
578 : ! Parameters for linear response solver
579 73 : IF (.NOT. ec_env%use_ls_solver) THEN
580 :
581 62 : WRITE (unit_nr, '(T2,A)') "MO Solver"
582 62 : WRITE (unit_nr, '()')
583 :
584 122 : SELECT CASE (ec_env%ks_solver)
585 : CASE (ec_diagonalization)
586 :
587 60 : SELECT CASE (ec_env%factorization)
588 : CASE (kg_cholesky)
589 60 : WRITE (unit_nr, '(T2,A,T61,A20)') "Factorization: ", "CHOLESKY"
590 : END SELECT
591 :
592 : CASE (ec_ot_diag)
593 :
594 : ! OT Diagonalization
595 : ! Initial guess : 1) block diagonal initial guess
596 : ! 2) GS-density matrix (might require trafo if basis diff)
597 :
598 2 : SELECT CASE (ec_env%ec_initial_guess)
599 : CASE (ec_ot_atomic)
600 1 : WRITE (unit_nr, '(T2,A,T61,A20)') "OT Diag initial guess: ", "ATOMIC"
601 : CASE (ec_ot_gs)
602 1 : WRITE (unit_nr, '(T2,A,T61,A20)') "OT Diag initial guess: ", "GROUND STATE DM"
603 : END SELECT
604 :
605 : CASE DEFAULT
606 62 : CPABORT("Unknown Diagonalization algorithm for Harris functional")
607 : END SELECT
608 :
609 : ELSE
610 :
611 11 : WRITE (unit_nr, '(T2,A)') "AO Solver"
612 11 : WRITE (unit_nr, '()')
613 :
614 11 : ls_env => ec_env%ls_env
615 11 : WRITE (unit_nr, '(T2,A,T61,E20.3)') "eps_filter:", ls_env%eps_filter
616 11 : WRITE (unit_nr, '(T2,A,T61,L20)') "fixed chemical potential (mu)", ls_env%fixed_mu
617 11 : WRITE (unit_nr, '(T2,A,T61,L20)') "Computing inv(S):", ls_env%needs_s_inv
618 11 : WRITE (unit_nr, '(T2,A,T61,L20)') "Computing sqrt(S):", ls_env%use_s_sqrt
619 11 : WRITE (unit_nr, '(T2,A,T61,L20)') "Computing S preconditioner ", ls_env%has_s_preconditioner
620 :
621 11 : IF (ls_env%use_s_sqrt) THEN
622 21 : SELECT CASE (ls_env%s_sqrt_method)
623 : CASE (ls_s_sqrt_ns)
624 10 : WRITE (unit_nr, '(T2,A,T61,A20)') "S sqrt method:", "NEWTONSCHULZ"
625 : CASE (ls_s_sqrt_proot)
626 1 : WRITE (unit_nr, '(T2,A,T61,A20)') "S sqrt method:", "PROOT"
627 : CASE DEFAULT
628 11 : CPABORT("Unknown sqrt method.")
629 : END SELECT
630 11 : WRITE (unit_nr, '(T2,A,T61,I20)') "S sqrt order:", ls_env%s_sqrt_order
631 : END IF
632 :
633 11 : SELECT CASE (ls_env%s_preconditioner_type)
634 : CASE (ls_s_preconditioner_none)
635 0 : WRITE (unit_nr, '(T2,A,T61,A20)') "S preconditioner type ", "NONE"
636 : CASE (ls_s_preconditioner_atomic)
637 11 : WRITE (unit_nr, '(T2,A,T61,A20)') "S preconditioner type ", "ATOMIC"
638 : CASE (ls_s_preconditioner_molecular)
639 11 : WRITE (unit_nr, '(T2,A,T61,A20)') "S preconditioner type ", "MOLECULAR"
640 : END SELECT
641 :
642 22 : SELECT CASE (ls_env%ls_mstruct%cluster_type)
643 : CASE (ls_cluster_atomic)
644 11 : WRITE (unit_nr, '(T2,A,T61,A20)') "Cluster type", ADJUSTR("ATOMIC")
645 : CASE (ls_cluster_molecular)
646 0 : WRITE (unit_nr, '(T2,A,T61,A20)') "Cluster type", ADJUSTR("MOLECULAR")
647 : CASE DEFAULT
648 11 : CPABORT("Unknown cluster type")
649 : END SELECT
650 :
651 : END IF
652 :
653 : END IF ! if ec_functional_harris
654 :
655 118 : WRITE (unit_nr, '(T2,A)') REPEAT("-", 79)
656 118 : WRITE (unit_nr, '()')
657 :
658 : END IF ! unit_nr
659 :
660 236 : CALL timestop(handle)
661 :
662 236 : END SUBROUTINE ec_write_input
663 :
664 : END MODULE ec_environment
|