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