(git:5e7fe52)
Loading...
Searching...
No Matches
hfx_admm_utils.F
Go to the documentation of this file.
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 Utilities for hfx and admm methods
10!>
11!>
12!> \par History
13!> refactoring 03-2011 [MI]
14!> Made GAPW compatible 12.2019 (A. Bussy)
15!> \author MI
16! **************************************************************************************************
21 USE admm_types, ONLY: admm_env_create,&
23 admm_type,&
31 USE cell_types, ONLY: cell_type,&
36 USE cp_dbcsr_api, ONLY: dbcsr_add,&
41 dbcsr_set,&
43 dbcsr_type_no_symmetry
51 USE cp_fm_types, ONLY: cp_fm_create,&
63 USE hfx_pw_methods, ONLY: pw_hfx
64 USE hfx_ri, ONLY: hfx_ri_update_forces,&
68 USE hfx_types, ONLY: hfx_type
69 USE input_constants, ONLY: &
86 USE kinds, ONLY: dp
90 USE kpoint_types, ONLY: get_kpoint_info,&
93 USE mathlib, ONLY: erfc_cutoff
99 USE pw_env_types, ONLY: pw_env_get,&
102 USE pw_pool_types, ONLY: pw_pool_type
103 USE pw_types, ONLY: pw_r3d_rs_type
109 USE qs_kind_types, ONLY: get_qs_kind,&
114 USE qs_ks_types, ONLY: qs_ks_env_type
116 USE qs_matrix_pools, ONLY: mpools_get
117 USE qs_mo_types, ONLY: allocate_mo_set,&
118 get_mo_set,&
130 USE qs_oce_types, ONLY: allocate_oce_set,&
135 USE qs_rho_types, ONLY: qs_rho_create,&
136 qs_rho_get,&
142 USE virial_types, ONLY: virial_type
144#include "./base/base_uses.f90"
145
146 IMPLICIT NONE
147
148 PRIVATE
149
150 ! *** Public subroutines ***
153
154 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'hfx_admm_utils'
155
156CONTAINS
157
158! **************************************************************************************************
159!> \brief ...
160!> \param qs_env ...
161!> \param calculate_forces ...
162!> \param ext_xc_section ...
163! **************************************************************************************************
164 SUBROUTINE hfx_admm_init(qs_env, calculate_forces, ext_xc_section)
165
166 TYPE(qs_environment_type), POINTER :: qs_env
167 LOGICAL, INTENT(IN), OPTIONAL :: calculate_forces
168 TYPE(section_vals_type), OPTIONAL, POINTER :: ext_xc_section
169
170 CHARACTER(LEN=*), PARAMETER :: routinen = 'hfx_admm_init'
171
172 INTEGER :: handle, ispin, n_rep_hf, nao_aux_fit, &
173 natoms, nelectron, nmo
174 LOGICAL :: calc_forces, do_kpoints, &
175 s_mstruct_changed, use_virial
176 REAL(dp) :: maxocc
177 TYPE(admm_type), POINTER :: admm_env
178 TYPE(cp_blacs_env_type), POINTER :: blacs_env
179 TYPE(cp_fm_struct_type), POINTER :: aux_fit_fm_struct
180 TYPE(cp_fm_type), POINTER :: mo_coeff_aux_fit
181 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_s_aux_fit_kp
182 TYPE(dbcsr_type), POINTER :: mo_coeff_b
183 TYPE(dft_control_type), POINTER :: dft_control
184 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos, mos_aux_fit
185 TYPE(mp_para_env_type), POINTER :: para_env
186 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
187 TYPE(qs_ks_env_type), POINTER :: ks_env
188 TYPE(section_vals_type), POINTER :: hfx_sections, input, xc_section
189 TYPE(virial_type), POINTER :: virial
190
191 CALL timeset(routinen, handle)
192
193 NULLIFY (admm_env, hfx_sections, mos, mos_aux_fit, para_env, virial, &
194 mo_coeff_aux_fit, xc_section, ks_env, dft_control, input, &
195 qs_kind_set, mo_coeff_b, aux_fit_fm_struct, blacs_env)
196
197 CALL get_qs_env(qs_env, &
198 mos=mos, &
199 admm_env=admm_env, &
200 para_env=para_env, &
201 blacs_env=blacs_env, &
202 s_mstruct_changed=s_mstruct_changed, &
203 ks_env=ks_env, &
204 dft_control=dft_control, &
205 input=input, &
206 virial=virial, &
207 do_kpoints=do_kpoints)
208
209 calc_forces = .false.
210 IF (PRESENT(calculate_forces)) calc_forces = .true.
211
212 hfx_sections => section_vals_get_subs_vals(input, "DFT%XC%HF")
213 IF (PRESENT(ext_xc_section)) hfx_sections => section_vals_get_subs_vals(ext_xc_section, "HF")
214
215 CALL section_vals_get(hfx_sections, n_repetition=n_rep_hf)
216 IF (n_rep_hf > 1) THEN
217 cpabort("ADMM can handle only one HF section.")
218 END IF
219
220 IF (.NOT. ASSOCIATED(admm_env)) THEN
221 ! setup admm environment
222 CALL get_qs_env(qs_env, input=input, natom=natoms, qs_kind_set=qs_kind_set)
223 CALL get_qs_kind_set(qs_kind_set, nsgf=nao_aux_fit, basis_type="AUX_FIT")
224 CALL admm_env_create(admm_env, dft_control%admm_control, mos, para_env, natoms, nao_aux_fit)
225 CALL set_qs_env(qs_env, admm_env=admm_env)
226 xc_section => section_vals_get_subs_vals(input, "DFT%XC")
227 IF (PRESENT(ext_xc_section)) xc_section => ext_xc_section
228 CALL create_admm_xc_section(x_data=qs_env%x_data, xc_section=xc_section, &
229 admm_env=admm_env)
230
231 ! Initialize the GAPW data types
232 IF (dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc) THEN
233 CALL init_admm_gapw(qs_env)
234 END IF
235
236 ! ADMM neighbor lists and overlap matrices
237 CALL admm_init_hamiltonians(admm_env, qs_env, "AUX_FIT")
238
239 !The aux_fit task list and densities
240 ALLOCATE (admm_env%rho_aux_fit)
241 CALL qs_rho_create(admm_env%rho_aux_fit)
242 ALLOCATE (admm_env%rho_aux_fit_buffer)
243 CALL qs_rho_create(admm_env%rho_aux_fit_buffer)
244 CALL admm_update_s_mstruct(admm_env, qs_env, "AUX_FIT")
245 IF (admm_env%do_gapw) CALL update_admm_gapw(qs_env)
246
247 !The ADMM KS matrices
248 CALL admm_alloc_ks_matrices(admm_env, qs_env)
249
250 !The aux_fit MOs and derivatives
251 ALLOCATE (mos_aux_fit(dft_control%nspins))
252 DO ispin = 1, dft_control%nspins
253 CALL get_mo_set(mo_set=mos(ispin), nmo=nmo, nelectron=nelectron, maxocc=maxocc)
254 CALL allocate_mo_set(mo_set=mos_aux_fit(ispin), &
255 nao=nao_aux_fit, &
256 nmo=nmo, &
257 nelectron=nelectron, &
258 n_el_f=real(nelectron, dp), &
259 maxocc=maxocc, &
260 flexible_electron_count=dft_control%relax_multiplicity)
261 END DO
262 admm_env%mos_aux_fit => mos_aux_fit
263
264 DO ispin = 1, dft_control%nspins
265 CALL get_mo_set(mo_set=mos(ispin), nmo=nmo)
266 CALL cp_fm_struct_create(aux_fit_fm_struct, context=blacs_env, para_env=para_env, &
267 nrow_global=nao_aux_fit, ncol_global=nmo)
268 CALL get_mo_set(mos_aux_fit(ispin), mo_coeff=mo_coeff_aux_fit, mo_coeff_b=mo_coeff_b)
269 IF (.NOT. ASSOCIATED(mo_coeff_aux_fit)) THEN
270 CALL init_mo_set(mos_aux_fit(ispin), fm_struct=aux_fit_fm_struct, &
271 name="qs_env%mo_aux_fit"//trim(adjustl(cp_to_string(ispin))))
272 END IF
273 CALL cp_fm_struct_release(aux_fit_fm_struct)
274
275 IF (.NOT. ASSOCIATED(mo_coeff_b)) THEN
276 CALL cp_fm_get_info(mos_aux_fit(ispin)%mo_coeff, ncol_global=nmo)
277 CALL dbcsr_init_p(mos_aux_fit(ispin)%mo_coeff_b)
278 CALL get_admm_env(admm_env, matrix_s_aux_fit_kp=matrix_s_aux_fit_kp)
279 CALL cp_dbcsr_m_by_n_from_row_template(mos_aux_fit(ispin)%mo_coeff_b, &
280 template=matrix_s_aux_fit_kp(1, 1)%matrix, &
281 n=nmo, sym=dbcsr_type_no_symmetry)
282 END IF
283 END DO
284
285 IF (qs_env%requires_mo_derivs) THEN
286 ALLOCATE (admm_env%mo_derivs_aux_fit(dft_control%nspins))
287 DO ispin = 1, dft_control%nspins
288 CALL get_mo_set(admm_env%mos_aux_fit(ispin), mo_coeff=mo_coeff_aux_fit)
289 CALL cp_fm_create(admm_env%mo_derivs_aux_fit(ispin), mo_coeff_aux_fit%matrix_struct)
290 END DO
291 END IF
292
293 IF (do_kpoints) THEN
294 block
295 TYPE(kpoint_type), POINTER :: kpoints
296 TYPE(mo_set_type), DIMENSION(:, :), POINTER :: mos_aux_fit_kp
297 TYPE(cp_fm_pool_p_type), DIMENSION(:), POINTER :: ao_mo_fm_pools_aux_fit
298 TYPE(cp_fm_struct_type), POINTER :: ao_ao_fm_struct
299 INTEGER :: ic, ik, ikk, is
300 INTEGER, PARAMETER :: nwork1 = 4
301 LOGICAL :: use_real_wfn
302
303 NULLIFY (ao_mo_fm_pools_aux_fit, mos_aux_fit_kp)
304
305 CALL get_qs_env(qs_env=qs_env, kpoints=kpoints)
306 CALL get_kpoint_info(kpoints, use_real_wfn=use_real_wfn)
307
308 !Test combinations of input values. So far, only ADMM2 is availavle
309 IF (.NOT. admm_env%purification_method == do_admm_purify_none) THEN
310 cpabort("Only ADMM_PURIFICATION_METHOD NONE implemeted for ADMM K-points")
311 END IF
312 IF (.NOT. (dft_control%admm_control%method == do_admm_basis_projection &
313 .OR. dft_control%admm_control%method == do_admm_charge_constrained_projection)) THEN
314 cpabort("Only BASIS_PROJECTION and CHARGE_CONSTRAINED_PROJECTION implemented for KP")
315 END IF
316 IF (admm_env%do_admms .OR. admm_env%do_admmp .OR. admm_env%do_admmq) THEN
317 IF (use_real_wfn) cpabort("Only KP-HFX ADMM2 is implemented with REAL wavefunctions")
318 END IF
319
320 CALL kpoint_initialize_mos(kpoints, admm_env%mos_aux_fit, for_aux_fit=.true.)
321
322 CALL mpools_get(kpoints%mpools_aux_fit, ao_mo_fm_pools=ao_mo_fm_pools_aux_fit)
323 DO ik = 1, SIZE(kpoints%kp_aux_env)
324 mos_aux_fit_kp => kpoints%kp_aux_env(ik)%kpoint_env%mos
325 ikk = kpoints%kp_range(1) + ik - 1
326 DO ispin = 1, SIZE(mos_aux_fit_kp, 2)
327 DO ic = 1, SIZE(mos_aux_fit_kp, 1)
328 CALL get_mo_set(mos_aux_fit_kp(ic, ispin), mo_coeff=mo_coeff_aux_fit, mo_coeff_b=mo_coeff_b)
329
330 ! no sparse matrix representation of kpoint MO vectors
331 cpassert(.NOT. ASSOCIATED(mo_coeff_b))
332
333 IF (.NOT. ASSOCIATED(mo_coeff_aux_fit)) THEN
334 CALL init_mo_set(mos_aux_fit_kp(ic, ispin), &
335 fm_pool=ao_mo_fm_pools_aux_fit(ispin)%pool, &
336 name="kpoints_"//trim(adjustl(cp_to_string(ikk)))// &
337 "%mo_aux_fit"//trim(adjustl(cp_to_string(ispin))))
338 END IF
339 END DO
340 END DO
341 END DO
342
343 ALLOCATE (admm_env%scf_work_aux_fit(nwork1))
344
345 ! create an ao_ao parallel matrix structure
346 CALL cp_fm_struct_create(ao_ao_fm_struct, context=blacs_env, para_env=para_env, &
347 nrow_global=nao_aux_fit, &
348 ncol_global=nao_aux_fit)
349
350 DO is = 1, nwork1
351 CALL cp_fm_create(admm_env%scf_work_aux_fit(is), &
352 matrix_struct=ao_ao_fm_struct, &
353 name="SCF-WORK_MATRIX-AUX-"//trim(adjustl(cp_to_string(is))))
354 END DO
355 CALL cp_fm_struct_release(ao_ao_fm_struct)
356
357 ! Create and populate the internal ADMM overlap matrices at each KP
358 CALL kpoint_calc_admm_matrices(qs_env, calc_forces)
359
360 END block
361 END IF
362
363 ELSE IF (s_mstruct_changed) THEN
364 CALL admm_init_hamiltonians(admm_env, qs_env, "AUX_FIT")
365 CALL admm_update_s_mstruct(admm_env, qs_env, "AUX_FIT")
366 CALL admm_alloc_ks_matrices(admm_env, qs_env)
367 IF (admm_env%do_gapw) CALL update_admm_gapw(qs_env)
368 IF (do_kpoints) CALL kpoint_calc_admm_matrices(qs_env, calc_forces)
369 END IF
370
371 IF (admm_env%do_gapw .AND. dft_control%do_admm_dm) THEN
372 cpabort("GAPW ADMM not implemented for MCWEENY or NONE_DM purification.")
373 END IF
374
375 !ADMMS and ADMMP stress tensors only available for close-shell systesms, because virial cannot
376 !be scaled by gsi spin component wise
377 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
378 IF (use_virial .AND. admm_env%do_admms .AND. dft_control%nspins == 2) THEN
379 cpabort("ADMMS stress tensor is only available for closed-shell systems")
380 END IF
381 IF (use_virial .AND. admm_env%do_admmp .AND. dft_control%nspins == 2) THEN
382 cpabort("ADMMP stress tensor is only available for closed-shell systems")
383 END IF
384
385 IF (dft_control%do_admm_dm .AND. .NOT. ASSOCIATED(admm_env%admm_dm)) THEN
386 CALL admm_dm_create(admm_env%admm_dm, dft_control%admm_control, nspins=dft_control%nspins, natoms=natoms)
387 END IF
388
389 CALL timestop(handle)
390
391 END SUBROUTINE hfx_admm_init
392
393! **************************************************************************************************
394!> \brief Minimal setup routine for admm_env
395!> No forces
396!> No k-points
397!> No DFT correction terms
398!> \param qs_env ...
399!> \param mos ...
400!> \param admm_env ...
401!> \param admm_control ...
402!> \param basis_type ...
403! **************************************************************************************************
404 SUBROUTINE aux_admm_init(qs_env, mos, admm_env, admm_control, basis_type)
405
406 TYPE(qs_environment_type), POINTER :: qs_env
407 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
408 TYPE(admm_type), POINTER :: admm_env
409 TYPE(admm_control_type), POINTER :: admm_control
410 CHARACTER(LEN=*) :: basis_type
411
412 CHARACTER(LEN=*), PARAMETER :: routinen = 'aux_admm_init'
413
414 INTEGER :: handle, ispin, nao_aux_fit, natoms, &
415 nelectron, nmo
416 LOGICAL :: do_kpoints
417 REAL(dp) :: maxocc
418 TYPE(cp_blacs_env_type), POINTER :: blacs_env
419 TYPE(cp_fm_struct_type), POINTER :: aux_fit_fm_struct
420 TYPE(cp_fm_type), POINTER :: mo_coeff_aux_fit
421 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_s_aux_fit_kp
422 TYPE(dbcsr_type), POINTER :: mo_coeff_b
423 TYPE(dft_control_type), POINTER :: dft_control
424 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos_aux_fit
425 TYPE(mp_para_env_type), POINTER :: para_env
426 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
427 TYPE(qs_ks_env_type), POINTER :: ks_env
428
429 CALL timeset(routinen, handle)
430
431 cpassert(.NOT. ASSOCIATED(admm_env))
432
433 CALL get_qs_env(qs_env, &
434 para_env=para_env, &
435 blacs_env=blacs_env, &
436 ks_env=ks_env, &
437 dft_control=dft_control, &
438 do_kpoints=do_kpoints)
439
440 cpassert(.NOT. do_kpoints)
441 IF (dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc) THEN
442 cpabort("AUX ADMM not possible with GAPW")
443 END IF
444
445 ! setup admm environment
446 CALL get_qs_env(qs_env, natom=natoms, qs_kind_set=qs_kind_set)
447 CALL get_qs_kind_set(qs_kind_set, nsgf=nao_aux_fit, basis_type=basis_type)
448 !
449 CALL admm_env_create(admm_env, admm_control, mos, para_env, natoms, nao_aux_fit)
450 ! no XC correction used
451 NULLIFY (admm_env%xc_section_aux, admm_env%xc_section_primary)
452 ! ADMM neighbor lists and overlap matrices
453 CALL admm_init_hamiltonians(admm_env, qs_env, basis_type)
454 NULLIFY (admm_env%rho_aux_fit, admm_env%rho_aux_fit_buffer)
455 !The ADMM KS matrices
456 CALL admm_alloc_ks_matrices(admm_env, qs_env)
457 !The aux_fit MOs and derivatives
458 ALLOCATE (mos_aux_fit(dft_control%nspins))
459 DO ispin = 1, dft_control%nspins
460 CALL get_mo_set(mo_set=mos(ispin), nmo=nmo, nelectron=nelectron, maxocc=maxocc)
461 CALL allocate_mo_set(mo_set=mos_aux_fit(ispin), nao=nao_aux_fit, nmo=nmo, &
462 nelectron=nelectron, n_el_f=real(nelectron, dp), &
463 maxocc=maxocc, flexible_electron_count=0.0_dp)
464 END DO
465 admm_env%mos_aux_fit => mos_aux_fit
466
467 DO ispin = 1, dft_control%nspins
468 CALL get_mo_set(mo_set=mos(ispin), nmo=nmo)
469 CALL cp_fm_struct_create(aux_fit_fm_struct, context=blacs_env, para_env=para_env, &
470 nrow_global=nao_aux_fit, ncol_global=nmo)
471 CALL get_mo_set(mos_aux_fit(ispin), mo_coeff=mo_coeff_aux_fit, mo_coeff_b=mo_coeff_b)
472 IF (.NOT. ASSOCIATED(mo_coeff_aux_fit)) THEN
473 CALL init_mo_set(mos_aux_fit(ispin), fm_struct=aux_fit_fm_struct, &
474 name="mo_aux_fit"//trim(adjustl(cp_to_string(ispin))))
475 END IF
476 CALL cp_fm_struct_release(aux_fit_fm_struct)
477
478 IF (.NOT. ASSOCIATED(mo_coeff_b)) THEN
479 CALL cp_fm_get_info(mos_aux_fit(ispin)%mo_coeff, ncol_global=nmo)
480 CALL dbcsr_init_p(mos_aux_fit(ispin)%mo_coeff_b)
481 CALL get_admm_env(admm_env, matrix_s_aux_fit_kp=matrix_s_aux_fit_kp)
482 CALL cp_dbcsr_m_by_n_from_row_template(mos_aux_fit(ispin)%mo_coeff_b, &
483 template=matrix_s_aux_fit_kp(1, 1)%matrix, &
484 n=nmo, sym=dbcsr_type_no_symmetry)
485 END IF
486 END DO
487
488 CALL timestop(handle)
489
490 END SUBROUTINE aux_admm_init
491
492! **************************************************************************************************
493!> \brief Sets up the admm_gapw env
494!> \param qs_env ...
495! **************************************************************************************************
496 SUBROUTINE init_admm_gapw(qs_env)
497
498 TYPE(qs_environment_type), POINTER :: qs_env
499
500 INTEGER :: ikind, nkind
501 TYPE(admm_gapw_r3d_rs_type), POINTER :: admm_gapw_env
502 TYPE(admm_type), POINTER :: admm_env
503 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
504 TYPE(dft_control_type), POINTER :: dft_control
505 TYPE(gto_basis_set_type), POINTER :: aux_fit_basis, aux_fit_soft_basis, &
506 orb_basis, soft_basis
507 TYPE(mp_para_env_type), POINTER :: para_env
508 TYPE(qs_kind_type), DIMENSION(:), POINTER :: admm_kind_set, qs_kind_set
509 TYPE(section_vals_type), POINTER :: input
510
511 NULLIFY (admm_kind_set, aux_fit_basis, atomic_kind_set, aux_fit_soft_basis, &
512 dft_control, input, orb_basis, para_env, qs_kind_set, soft_basis)
513
514 CALL get_qs_env(qs_env, admm_env=admm_env, &
515 atomic_kind_set=atomic_kind_set, &
516 dft_control=dft_control, &
517 input=input, &
518 para_env=para_env, &
519 qs_kind_set=qs_kind_set)
520
521 admm_env%do_gapw = .true.
522 ALLOCATE (admm_env%admm_gapw_env)
523 admm_gapw_env => admm_env%admm_gapw_env
524 NULLIFY (admm_gapw_env%local_rho_set)
525 NULLIFY (admm_gapw_env%admm_kind_set)
526 NULLIFY (admm_gapw_env%task_list)
527
528 !Create a new kind set for the ADMM stuff (paw_proj soft AUX_FIT basis, etc)
529 nkind = SIZE(qs_kind_set)
530 ALLOCATE (admm_gapw_env%admm_kind_set(nkind))
531 admm_kind_set => admm_gapw_env%admm_kind_set
532
533 !In this new kind set, we want the AUX_FIT basis to be known as ORB, such that GAPW routines work
534 DO ikind = 1, nkind
535 !copying over simple data of interest from qs_kind_set
536 admm_kind_set(ikind)%name = qs_kind_set(ikind)%name
537 admm_kind_set(ikind)%element_symbol = qs_kind_set(ikind)%element_symbol
538 admm_kind_set(ikind)%natom = qs_kind_set(ikind)%natom
539 admm_kind_set(ikind)%hard_radius = qs_kind_set(ikind)%hard_radius
540 admm_kind_set(ikind)%max_rad_local = qs_kind_set(ikind)%max_rad_local
541 admm_kind_set(ikind)%gpw_type_forced = qs_kind_set(ikind)%gpw_type_forced
542 admm_kind_set(ikind)%ngrid_rad = qs_kind_set(ikind)%ngrid_rad
543 admm_kind_set(ikind)%ngrid_ang = qs_kind_set(ikind)%ngrid_ang
544
545 !copying potentials of interest from qs_kind_set
546 IF (ASSOCIATED(qs_kind_set(ikind)%all_potential)) THEN
547 CALL copy_potential(qs_kind_set(ikind)%all_potential, admm_kind_set(ikind)%all_potential)
548 END IF
549 IF (ASSOCIATED(qs_kind_set(ikind)%gth_potential)) THEN
550 CALL copy_potential(qs_kind_set(ikind)%gth_potential, admm_kind_set(ikind)%gth_potential)
551 END IF
552 IF (ASSOCIATED(qs_kind_set(ikind)%sgp_potential)) THEN
553 CALL copy_potential(qs_kind_set(ikind)%sgp_potential, admm_kind_set(ikind)%sgp_potential)
554 END IF
555
556 NULLIFY (orb_basis)
557 CALL get_qs_kind(qs_kind_set(ikind), basis_set=aux_fit_basis, basis_type="AUX_FIT")
558 CALL copy_gto_basis_set(aux_fit_basis, orb_basis)
559 CALL add_basis_set_to_container(admm_kind_set(ikind)%basis_sets, orb_basis, "ORB")
560 END DO
561
562 !Create the corresponding soft basis set (and projectors)
563 CALL init_gapw_basis_set(admm_kind_set, dft_control%qs_control, input, &
564 modify_qs_control=.false.)
565
566 !Make sure the basis and the projectors are well initialized
567 CALL init_interaction_radii(dft_control%qs_control, admm_kind_set)
568
569 !We also init the atomic grids and harmonics
570 CALL local_rho_set_create(admm_gapw_env%local_rho_set)
571 CALL init_rho_atom(admm_gapw_env%local_rho_set%rho_atom_set, &
572 atomic_kind_set, admm_kind_set, dft_control, para_env)
573
574 !Make sure that any NLCC potential is well initialized
575 CALL init_gapw_nlcc(admm_kind_set)
576
577 !Need to have access to the soft AUX_FIT basis from the qs_env => add it to the qs_kinds
578 DO ikind = 1, nkind
579 NULLIFY (aux_fit_soft_basis)
580 CALL get_qs_kind(admm_kind_set(ikind), basis_set=soft_basis, basis_type="ORB_SOFT")
581 CALL copy_gto_basis_set(soft_basis, aux_fit_soft_basis)
582 CALL add_basis_set_to_container(qs_kind_set(ikind)%basis_sets, aux_fit_soft_basis, "AUX_FIT_SOFT")
583 END DO
584
585 END SUBROUTINE init_admm_gapw
586
587! **************************************************************************************************
588!> \brief Builds the ADMM nmeighbor lists and overlap matrix on the model of qs_energies_init_hamiltonians()
589!> \param admm_env ...
590!> \param qs_env ...
591!> \param aux_basis_type ...
592! **************************************************************************************************
593 SUBROUTINE admm_init_hamiltonians(admm_env, qs_env, aux_basis_type)
594
595 TYPE(admm_type), POINTER :: admm_env
596 TYPE(qs_environment_type), POINTER :: qs_env
597 CHARACTER(len=*) :: aux_basis_type
598
599 CHARACTER(len=*), PARAMETER :: routinen = 'admm_init_hamiltonians'
600
601 INTEGER :: handle, hfx_pot, ikind, nkind
602 LOGICAL :: do_kpoints, mic, molecule_only
603 LOGICAL, ALLOCATABLE, DIMENSION(:) :: aux_fit_present, orb_present
604 REAL(dp) :: eps_schwarz, omega, pdist, roperator, &
605 subcells
606 REAL(dp), ALLOCATABLE, DIMENSION(:) :: aux_fit_radius, orb_radius
607 REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: pair_radius
608 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
609 TYPE(cell_type), POINTER :: cell
610 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_s_aux_fit_kp, &
611 matrix_s_aux_fit_vs_orb_kp
612 TYPE(dft_control_type), POINTER :: dft_control
613 TYPE(distribution_1d_type), POINTER :: distribution_1d
614 TYPE(distribution_2d_type), POINTER :: distribution_2d
615 TYPE(gto_basis_set_type), POINTER :: aux_fit_basis_set, orb_basis_set
616 TYPE(kpoint_type), POINTER :: kpoints
617 TYPE(local_atoms_type), ALLOCATABLE, DIMENSION(:) :: atom2d
618 TYPE(molecule_type), DIMENSION(:), POINTER :: molecule_set
619 TYPE(mp_para_env_type), POINTER :: para_env
620 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
621 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
622 TYPE(qs_ks_env_type), POINTER :: ks_env
623 TYPE(section_vals_type), POINTER :: hfx_sections, neighbor_list_section
624
625 NULLIFY (particle_set, cell, kpoints, distribution_1d, distribution_2d, molecule_set, &
626 atomic_kind_set, dft_control, neighbor_list_section, aux_fit_basis_set, orb_basis_set, &
627 ks_env, para_env, qs_kind_set, matrix_s_aux_fit_kp, matrix_s_aux_fit_vs_orb_kp)
628
629 CALL timeset(routinen, handle)
630
631 CALL get_qs_env(qs_env, nkind=nkind, particle_set=particle_set, cell=cell, kpoints=kpoints, &
632 local_particles=distribution_1d, distribution_2d=distribution_2d, &
633 molecule_set=molecule_set, atomic_kind_set=atomic_kind_set, do_kpoints=do_kpoints, &
634 dft_control=dft_control, para_env=para_env, qs_kind_set=qs_kind_set)
635 ALLOCATE (orb_present(nkind), aux_fit_present(nkind))
636 ALLOCATE (orb_radius(nkind), aux_fit_radius(nkind), pair_radius(nkind, nkind))
637 aux_fit_radius(:) = 0.0_dp
638
639 molecule_only = .false.
640 IF (dft_control%qs_control%do_kg) molecule_only = .true.
641 mic = molecule_only
642 IF (kpoints%nkp > 0) THEN
643 mic = .false.
644 ELSE IF (dft_control%qs_control%semi_empirical) THEN
645 mic = .true.
646 END IF
647
648 pdist = dft_control%qs_control%pairlist_radius
649
650 CALL section_vals_val_get(qs_env%input, "DFT%SUBCELLS", r_val=subcells)
651 neighbor_list_section => section_vals_get_subs_vals(qs_env%input, "DFT%PRINT%NEIGHBOR_LISTS")
652
653 ALLOCATE (atom2d(nkind))
654 CALL atom2d_build(atom2d, distribution_1d, distribution_2d, atomic_kind_set, &
655 molecule_set, molecule_only, particle_set=particle_set)
656
657 DO ikind = 1, nkind
658 CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set, basis_type="ORB")
659 IF (ASSOCIATED(orb_basis_set)) THEN
660 orb_present(ikind) = .true.
661 CALL get_gto_basis_set(gto_basis_set=orb_basis_set, kind_radius=orb_radius(ikind))
662 ELSE
663 orb_present(ikind) = .false.
664 END IF
665
666 CALL get_qs_kind(qs_kind_set(ikind), basis_set=aux_fit_basis_set, basis_type=aux_basis_type)
667 IF (ASSOCIATED(aux_fit_basis_set)) THEN
668 aux_fit_present(ikind) = .true.
669 CALL get_gto_basis_set(gto_basis_set=aux_fit_basis_set, kind_radius=aux_fit_radius(ikind))
670 ELSE
671 aux_fit_present(ikind) = .false.
672 END IF
673 END DO
674
675 IF (pdist < 0.0_dp) THEN
676 pdist = max(plane_distance(1, 0, 0, cell), &
677 plane_distance(0, 1, 0, cell), &
678 plane_distance(0, 0, 1, cell))
679 END IF
680
681 !In case of K-points, we need to add the HFX potential range to sab_aux_fit, because it is used
682 !to populate AUX density and KS matrices
683 roperator = 0.0_dp
684 IF (do_kpoints) THEN
685 hfx_sections => section_vals_get_subs_vals(qs_env%input, "DFT%XC%HF")
686 CALL section_vals_val_get(hfx_sections, "INTERACTION_POTENTIAL%POTENTIAL_TYPE", i_val=hfx_pot)
687
688 SELECT CASE (hfx_pot)
689 CASE (do_potential_id)
690 roperator = 0.0_dp
691 CASE (do_potential_truncated)
692 CALL section_vals_val_get(hfx_sections, "INTERACTION_POTENTIAL%CUTOFF_RADIUS", r_val=roperator)
693 CASE (do_potential_mix_cl_trunc)
694 CALL section_vals_val_get(hfx_sections, "INTERACTION_POTENTIAL%CUTOFF_RADIUS", r_val=roperator)
695 CASE (do_potential_short)
696 CALL section_vals_val_get(hfx_sections, "INTERACTION_POTENTIAL%OMEGA", r_val=omega)
697 CALL section_vals_val_get(hfx_sections, "SCREENING%EPS_SCHWARZ", r_val=eps_schwarz)
698 CALL erfc_cutoff(eps_schwarz, omega, roperator)
699 CASE DEFAULT
700 cpabort("HFX potential not available for K-points (NYI)")
701 END SELECT
702 END IF
703
704 CALL pair_radius_setup(aux_fit_present, aux_fit_present, aux_fit_radius, aux_fit_radius, pair_radius, pdist)
705 pair_radius = pair_radius + cutoff_screen_factor*roperator
706 CALL build_neighbor_lists(admm_env%sab_aux_fit, particle_set, atom2d, cell, pair_radius, &
707 mic=mic, molecular=molecule_only, subcells=subcells, nlname="sab_aux_fit", &
708 stable_images=kpoints%symmetry)
709 CALL build_neighbor_lists(admm_env%sab_aux_fit_asymm, particle_set, atom2d, cell, pair_radius, &
710 mic=mic, symmetric=.false., molecular=molecule_only, subcells=subcells, &
711 nlname="sab_aux_fit_asymm", stable_images=kpoints%symmetry)
712 CALL pair_radius_setup(aux_fit_present, orb_present, aux_fit_radius, orb_radius, pair_radius)
713 CALL build_neighbor_lists(admm_env%sab_aux_fit_vs_orb, particle_set, atom2d, cell, pair_radius, &
714 mic=mic, symmetric=.false., molecular=molecule_only, subcells=subcells, &
715 nlname="sab_aux_fit_vs_orb", stable_images=kpoints%symmetry)
716
717 CALL write_neighbor_lists(admm_env%sab_aux_fit, particle_set, cell, para_env, neighbor_list_section, &
718 "/SAB_AUX_FIT", "sab_aux_fit", "AUX_FIT_ORBITAL AUX_FIT_ORBITAL")
719 CALL write_neighbor_lists(admm_env%sab_aux_fit_vs_orb, particle_set, cell, para_env, neighbor_list_section, &
720 "/SAB_AUX_FIT_VS_ORB", "sab_aux_fit_vs_orb", "ORBITAL AUX_FIT_ORBITAL")
721
722 CALL atom2d_cleanup(atom2d)
723
724 !The ADMM overlap matrices (initially in qs_core_hamiltonian.F)
725 CALL get_qs_env(qs_env, ks_env=ks_env)
726
727 CALL kpoint_transitional_release(admm_env%matrix_s_aux_fit)
728 CALL build_overlap_matrix(ks_env, matrixkp_s=matrix_s_aux_fit_kp, &
729 matrix_name="AUX_FIT_OVERLAP", &
730 basis_type_a=aux_basis_type, &
731 basis_type_b=aux_basis_type, &
732 sab_nl=admm_env%sab_aux_fit)
733 CALL set_2d_pointer(admm_env%matrix_s_aux_fit, matrix_s_aux_fit_kp)
734 CALL kpoint_transitional_release(admm_env%matrix_s_aux_fit_vs_orb)
735 CALL build_overlap_matrix(ks_env, matrixkp_s=matrix_s_aux_fit_vs_orb_kp, &
736 matrix_name="MIXED_OVERLAP", &
737 basis_type_a=aux_basis_type, &
738 basis_type_b="ORB", &
739 sab_nl=admm_env%sab_aux_fit_vs_orb)
740 CALL set_2d_pointer(admm_env%matrix_s_aux_fit_vs_orb, matrix_s_aux_fit_vs_orb_kp)
741
742 CALL timestop(handle)
743
744 END SUBROUTINE admm_init_hamiltonians
745
746! **************************************************************************************************
747!> \brief Updates the ADMM task_list and density based on the model of qs_env_update_s_mstruct()
748!> \param admm_env ...
749!> \param qs_env ...
750!> \param aux_basis_type ...
751! **************************************************************************************************
752 SUBROUTINE admm_update_s_mstruct(admm_env, qs_env, aux_basis_type)
753
754 TYPE(admm_type), POINTER :: admm_env
755 TYPE(qs_environment_type), POINTER :: qs_env
756 CHARACTER(len=*) :: aux_basis_type
757
758 CHARACTER(len=*), PARAMETER :: routinen = 'admm_update_s_mstruct'
759
760 INTEGER :: handle
761 LOGICAL :: skip_load_balance_distributed
762 TYPE(dft_control_type), POINTER :: dft_control
763 TYPE(qs_ks_env_type), POINTER :: ks_env
764
765 NULLIFY (ks_env, dft_control)
766
767 CALL timeset(routinen, handle)
768
769 CALL get_qs_env(qs_env, ks_env=ks_env, dft_control=dft_control)
770
771 !The aux_fit task_list
772 skip_load_balance_distributed = dft_control%qs_control%skip_load_balance_distributed
773 IF (ASSOCIATED(admm_env%task_list_aux_fit)) CALL deallocate_task_list(admm_env%task_list_aux_fit)
774 CALL allocate_task_list(admm_env%task_list_aux_fit)
775 CALL generate_qs_task_list(ks_env, admm_env%task_list_aux_fit, basis_type=aux_basis_type, &
776 reorder_rs_grid_ranks=.false., &
777 skip_load_balance_distributed=skip_load_balance_distributed, &
778 sab_orb_external=admm_env%sab_aux_fit)
779
780 !The aux_fit densities
781 CALL qs_rho_rebuild(admm_env%rho_aux_fit, qs_env=qs_env, admm=.true.)
782 CALL qs_rho_rebuild(admm_env%rho_aux_fit_buffer, qs_env=qs_env, admm=.true.)
783
784 CALL timestop(handle)
785
786 END SUBROUTINE admm_update_s_mstruct
787
788! **************************************************************************************************
789!> \brief Update the admm_gapw_env internals to the current qs_env (i.e. atomic positions)
790!> \param qs_env ...
791! **************************************************************************************************
792 SUBROUTINE update_admm_gapw(qs_env)
793
794 TYPE(qs_environment_type), POINTER :: qs_env
795
796 CHARACTER(len=*), PARAMETER :: routinen = 'update_admm_gapw'
797
798 INTEGER :: handle, ikind, nkind
799 LOGICAL :: paw_atom
800 LOGICAL, ALLOCATABLE, DIMENSION(:) :: aux_present, oce_present
801 REAL(dp) :: subcells
802 REAL(dp), ALLOCATABLE, DIMENSION(:) :: aux_radius, oce_radius
803 REAL(dp), ALLOCATABLE, DIMENSION(:, :) :: pair_radius
804 TYPE(admm_gapw_r3d_rs_type), POINTER :: admm_gapw_env
805 TYPE(admm_type), POINTER :: admm_env
806 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
807 TYPE(cell_type), POINTER :: cell
808 TYPE(dft_control_type), POINTER :: dft_control
809 TYPE(distribution_1d_type), POINTER :: distribution_1d
810 TYPE(distribution_2d_type), POINTER :: distribution_2d
811 TYPE(gto_basis_set_type), POINTER :: aux_fit_basis
812 TYPE(local_atoms_type), ALLOCATABLE, DIMENSION(:) :: atom2d
813 TYPE(molecule_type), DIMENSION(:), POINTER :: molecule_set
814 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
815 POINTER :: sap_oce
816 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
817 TYPE(paw_proj_set_type), POINTER :: paw_proj
818 TYPE(qs_kind_type), DIMENSION(:), POINTER :: admm_kind_set, qs_kind_set
819 TYPE(qs_ks_env_type), POINTER :: ks_env
820
821 NULLIFY (ks_env, qs_kind_set, admm_kind_set, aux_fit_basis, cell, distribution_1d)
822 NULLIFY (distribution_2d, paw_proj, particle_set, molecule_set, admm_env, admm_gapw_env)
823 NULLIFY (dft_control, atomic_kind_set, sap_oce)
824
825 CALL timeset(routinen, handle)
826
827 CALL get_qs_env(qs_env, ks_env=ks_env, qs_kind_set=qs_kind_set, admm_env=admm_env, &
828 dft_control=dft_control)
829 admm_gapw_env => admm_env%admm_gapw_env
830 admm_kind_set => admm_gapw_env%admm_kind_set
831 nkind = SIZE(qs_kind_set)
832
833 !Update the task lisft for the AUX_FIT_SOFT basis
834 IF (ASSOCIATED(admm_gapw_env%task_list)) CALL deallocate_task_list(admm_gapw_env%task_list)
835 CALL allocate_task_list(admm_gapw_env%task_list)
836
837 !note: we set soft_valid to .FALSE. want to use AUX_FIT_SOFT and not the normal ORB SOFT basis
838 CALL generate_qs_task_list(ks_env, admm_gapw_env%task_list, basis_type="AUX_FIT_SOFT", &
839 reorder_rs_grid_ranks=.false., &
840 skip_load_balance_distributed=dft_control%qs_control%skip_load_balance_distributed, &
841 sab_orb_external=admm_env%sab_aux_fit)
842
843 !Update the precomputed oce integrals
844 !a sap_oce neighbor list is required => build it here
845 ALLOCATE (aux_present(nkind), oce_present(nkind))
846 aux_present = .false.; oce_present = .false.
847 ALLOCATE (aux_radius(nkind), oce_radius(nkind))
848 aux_radius = 0.0_dp; oce_radius = 0.0_dp
849
850 DO ikind = 1, nkind
851 CALL get_qs_kind(qs_kind_set(ikind), basis_set=aux_fit_basis, basis_type="AUX_FIT")
852 IF (ASSOCIATED(aux_fit_basis)) THEN
853 aux_present(ikind) = .true.
854 CALL get_gto_basis_set(aux_fit_basis, kind_radius=aux_radius(ikind))
855 END IF
856
857 !note: get oce info from admm_kind_set
858 CALL get_qs_kind(admm_kind_set(ikind), paw_atom=paw_atom, paw_proj_set=paw_proj)
859 IF (paw_atom) THEN
860 oce_present(ikind) = .true.
861 CALL get_paw_proj_set(paw_proj, rcprj=oce_radius(ikind))
862 END IF
863 END DO
864
865 ALLOCATE (pair_radius(nkind, nkind))
866 pair_radius = 0.0_dp
867 CALL pair_radius_setup(aux_present, oce_present, aux_radius, oce_radius, pair_radius)
868
869 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, cell=cell, &
870 distribution_2d=distribution_2d, local_particles=distribution_1d, &
871 particle_set=particle_set, molecule_set=molecule_set)
872 CALL section_vals_val_get(qs_env%input, "DFT%SUBCELLS", r_val=subcells)
873
874 ALLOCATE (atom2d(nkind))
875 CALL atom2d_build(atom2d, distribution_1d, distribution_2d, atomic_kind_set, &
876 molecule_set, .false., particle_set)
877 CALL build_neighbor_lists(sap_oce, particle_set, atom2d, cell, pair_radius, &
878 subcells=subcells, operator_type="ABBA", nlname="AUX_PAW-PRJ")
879 CALL atom2d_cleanup(atom2d)
880
881 !actually compute the oce matrices
882 CALL create_oce_set(admm_gapw_env%oce)
883 CALL allocate_oce_set(admm_gapw_env%oce, nkind)
884
885 !always compute the derivative, cheap anyways
886 CALL build_oce_matrices(admm_gapw_env%oce%intac, calculate_forces=.true., nder=1, &
887 qs_kind_set=admm_kind_set, particle_set=particle_set, &
888 sap_oce=sap_oce, eps_fit=dft_control%qs_control%gapw_control%eps_fit)
889
890 CALL release_neighbor_list_sets(sap_oce)
891
892 CALL timestop(handle)
893
894 END SUBROUTINE update_admm_gapw
895
896! **************************************************************************************************
897!> \brief Allocates the various ADMM KS matrices
898!> \param admm_env ...
899!> \param qs_env ...
900! **************************************************************************************************
901 SUBROUTINE admm_alloc_ks_matrices(admm_env, qs_env)
902
903 TYPE(admm_type), POINTER :: admm_env
904 TYPE(qs_environment_type), POINTER :: qs_env
905
906 CHARACTER(len=*), PARAMETER :: routinen = 'admm_alloc_ks_matrices'
907
908 INTEGER :: handle, ic, ispin
909 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks_aux_fit_dft_kp, &
910 matrix_ks_aux_fit_hfx_kp, &
911 matrix_ks_aux_fit_kp, &
912 matrix_s_aux_fit_kp
913 TYPE(dft_control_type), POINTER :: dft_control
914
915 NULLIFY (dft_control, matrix_s_aux_fit_kp, matrix_ks_aux_fit_kp, matrix_ks_aux_fit_dft_kp, matrix_ks_aux_fit_hfx_kp)
916
917 CALL timeset(routinen, handle)
918
919 CALL get_qs_env(qs_env, dft_control=dft_control)
920 CALL get_admm_env(admm_env, matrix_s_aux_fit_kp=matrix_s_aux_fit_kp)
921
922 CALL kpoint_transitional_release(admm_env%matrix_ks_aux_fit)
923 CALL kpoint_transitional_release(admm_env%matrix_ks_aux_fit_dft)
924 CALL kpoint_transitional_release(admm_env%matrix_ks_aux_fit_hfx)
925
926 CALL dbcsr_allocate_matrix_set(matrix_ks_aux_fit_kp, dft_control%nspins, dft_control%nimages)
927 CALL dbcsr_allocate_matrix_set(matrix_ks_aux_fit_dft_kp, dft_control%nspins, dft_control%nimages)
928 CALL dbcsr_allocate_matrix_set(matrix_ks_aux_fit_hfx_kp, dft_control%nspins, dft_control%nimages)
929
930 DO ispin = 1, dft_control%nspins
931 DO ic = 1, dft_control%nimages
932 ALLOCATE (matrix_ks_aux_fit_kp(ispin, ic)%matrix)
933 CALL dbcsr_create(matrix_ks_aux_fit_kp(ispin, ic)%matrix, template=matrix_s_aux_fit_kp(1, ic)%matrix, &
934 name="KOHN-SHAM_MATRIX for ADMM")
935 CALL cp_dbcsr_alloc_block_from_nbl(matrix_ks_aux_fit_kp(ispin, ic)%matrix, admm_env%sab_aux_fit)
936 CALL dbcsr_set(matrix_ks_aux_fit_kp(ispin, ic)%matrix, 0.0_dp)
937
938 ALLOCATE (matrix_ks_aux_fit_dft_kp(ispin, ic)%matrix)
939 CALL dbcsr_create(matrix_ks_aux_fit_dft_kp(ispin, ic)%matrix, template=matrix_s_aux_fit_kp(1, 1)%matrix, &
940 name="KOHN-SHAM_MATRIX for ADMM")
941 CALL cp_dbcsr_alloc_block_from_nbl(matrix_ks_aux_fit_dft_kp(ispin, ic)%matrix, admm_env%sab_aux_fit)
942 CALL dbcsr_set(matrix_ks_aux_fit_dft_kp(ispin, ic)%matrix, 0.0_dp)
943
944 ALLOCATE (matrix_ks_aux_fit_hfx_kp(ispin, ic)%matrix)
945 CALL dbcsr_create(matrix_ks_aux_fit_hfx_kp(ispin, ic)%matrix, template=matrix_s_aux_fit_kp(1, 1)%matrix, &
946 name="KOHN-SHAM_MATRIX for ADMM")
947 CALL cp_dbcsr_alloc_block_from_nbl(matrix_ks_aux_fit_hfx_kp(ispin, ic)%matrix, admm_env%sab_aux_fit)
948 CALL dbcsr_set(matrix_ks_aux_fit_hfx_kp(ispin, ic)%matrix, 0.0_dp)
949 END DO
950 END DO
951
952 CALL set_admm_env(admm_env, &
953 matrix_ks_aux_fit_kp=matrix_ks_aux_fit_kp, &
954 matrix_ks_aux_fit_dft_kp=matrix_ks_aux_fit_dft_kp, &
955 matrix_ks_aux_fit_hfx_kp=matrix_ks_aux_fit_hfx_kp)
956
957 CALL timestop(handle)
958
959 END SUBROUTINE admm_alloc_ks_matrices
960
961! **************************************************************************************************
962!> \brief Add the HFX K-point contribution to the real-space Hamiltonians
963!> \param qs_env ...
964!> \param matrix_ks ...
965!> \param energy ...
966!> \param calculate_forces ...
967! **************************************************************************************************
968 SUBROUTINE hfx_ks_matrix_kp(qs_env, matrix_ks, energy, calculate_forces)
969 TYPE(qs_environment_type), POINTER :: qs_env
970 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks
971 TYPE(qs_energy_type), POINTER :: energy
972 LOGICAL, INTENT(in) :: calculate_forces
973
974 CHARACTER(LEN=*), PARAMETER :: routinen = 'hfx_ks_matrix_kp'
975
976 INTEGER :: handle, img, irep, ispin, n_rep_hf, &
977 nimages, nspins
978 LOGICAL :: do_adiabatic_rescaling, &
979 s_mstruct_changed, use_virial
980 REAL(dp) :: eh1, ehfx, eold
981 REAL(dp), ALLOCATABLE, DIMENSION(:) :: hf_energy
982 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks_aux_fit_im, matrix_ks_im
983 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_h, matrix_ks_aux_fit_hfx_kp, &
984 matrix_ks_aux_fit_kp, matrix_ks_orb, &
985 rho_ao_orb
986 TYPE(dft_control_type), POINTER :: dft_control
987 TYPE(hfx_type), DIMENSION(:, :), POINTER :: x_data
988 TYPE(mp_para_env_type), POINTER :: para_env
989 TYPE(pw_env_type), POINTER :: pw_env
990 TYPE(pw_poisson_type), POINTER :: poisson_env
991 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
992 TYPE(qs_rho_type), POINTER :: rho_orb
993 TYPE(section_vals_type), POINTER :: adiabatic_rescaling_section, &
994 hfx_sections, input
995 TYPE(virial_type), POINTER :: virial
996
997 CALL timeset(routinen, handle)
998
999 NULLIFY (auxbas_pw_pool, dft_control, hfx_sections, input, &
1000 para_env, poisson_env, pw_env, virial, matrix_ks_im, &
1001 matrix_ks_orb, rho_ao_orb, matrix_h, matrix_ks_aux_fit_kp, &
1002 matrix_ks_aux_fit_im, matrix_ks_aux_fit_hfx_kp)
1003
1004 CALL get_qs_env(qs_env=qs_env, &
1005 dft_control=dft_control, &
1006 input=input, &
1007 matrix_h_kp=matrix_h, &
1008 para_env=para_env, &
1009 pw_env=pw_env, &
1010 virial=virial, &
1011 matrix_ks_im=matrix_ks_im, &
1012 s_mstruct_changed=s_mstruct_changed, &
1013 x_data=x_data)
1014
1015 ! No RTP
1016 IF (qs_env%run_rtp) cpabort("No RTP implementation with K-points HFX")
1017
1018 ! No adiabatic rescaling
1019 adiabatic_rescaling_section => section_vals_get_subs_vals(input, "DFT%XC%ADIABATIC_RESCALING")
1020 CALL section_vals_get(adiabatic_rescaling_section, explicit=do_adiabatic_rescaling)
1021 IF (do_adiabatic_rescaling) cpabort("No adiabatic rescaling implementation with K-points HFX")
1022
1023 IF (dft_control%do_admm) THEN
1024 CALL get_admm_env(qs_env%admm_env, matrix_ks_aux_fit_kp=matrix_ks_aux_fit_kp, &
1025 matrix_ks_aux_fit_im=matrix_ks_aux_fit_im, &
1026 matrix_ks_aux_fit_hfx_kp=matrix_ks_aux_fit_hfx_kp)
1027 END IF
1028
1029 nspins = dft_control%nspins
1030 nimages = dft_control%nimages
1031
1032 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
1033 IF (use_virial .AND. calculate_forces) virial%pv_fock_4c = 0.0_dp
1034
1035 hfx_sections => section_vals_get_subs_vals(input, "DFT%XC%HF")
1036 CALL section_vals_get(hfx_sections, n_repetition=n_rep_hf)
1037
1038 ! *** Initialize the auxiliary ks matrix to zero if required
1039 IF (dft_control%do_admm) THEN
1040 DO ispin = 1, nspins
1041 DO img = 1, nimages
1042 CALL dbcsr_set(matrix_ks_aux_fit_kp(ispin, img)%matrix, 0.0_dp)
1043 END DO
1044 END DO
1045 END IF
1046 DO ispin = 1, nspins
1047 DO img = 1, nimages
1048 CALL dbcsr_set(matrix_ks(ispin, img)%matrix, 0.0_dp)
1049 END DO
1050 END DO
1051
1052 ALLOCATE (hf_energy(n_rep_hf))
1053
1054 eold = 0.0_dp
1055
1056 DO irep = 1, n_rep_hf
1057
1058 ! fetch the correct matrices for normal HFX or ADMM
1059 IF (dft_control%do_admm) THEN
1060 CALL get_admm_env(qs_env%admm_env, matrix_ks_aux_fit_kp=matrix_ks_orb, rho_aux_fit=rho_orb)
1061 ELSE
1062 CALL get_qs_env(qs_env=qs_env, matrix_ks_kp=matrix_ks_orb, rho=rho_orb)
1063 END IF
1064 CALL qs_rho_get(rho_struct=rho_orb, rho_ao_kp=rho_ao_orb)
1065
1066 ! Finally the real hfx calulation
1067 ehfx = 0.0_dp
1068
1069 IF (.NOT. x_data(irep, 1)%do_hfx_ri) THEN
1070 cpabort("Only RI-HFX is implemented for K-points")
1071 END IF
1072
1073 CALL hfx_ri_update_ks_kp(qs_env, x_data(irep, 1)%ri_data, matrix_ks_orb, ehfx, &
1074 rho_ao_orb, s_mstruct_changed, nspins, &
1075 x_data(irep, 1)%general_parameter%fraction)
1076
1077 IF (calculate_forces) THEN
1078 !Scale auxiliary density matrix for ADMMP (see Merlot2014) with gsi(ispin) to scale force
1079 IF (dft_control%do_admm) THEN
1080 CALL scale_dm(qs_env, rho_ao_orb, scale_back=.false.)
1081 END IF
1082
1083 CALL hfx_ri_update_forces_kp(qs_env, x_data(irep, 1)%ri_data, nspins, &
1084 x_data(irep, 1)%general_parameter%fraction, &
1085 rho_ao_orb, use_virial=use_virial)
1086
1087 IF (dft_control%do_admm) THEN
1088 CALL scale_dm(qs_env, rho_ao_orb, scale_back=.true.)
1089 END IF
1090 END IF
1091
1092 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, poisson_env=poisson_env)
1093 eh1 = ehfx - eold
1094 CALL pw_hfx(qs_env, eh1, hfx_sections, poisson_env, auxbas_pw_pool, irep)
1095 eold = ehfx
1096
1097 END DO
1098
1099 ! *** Set the total HFX energy
1100 energy%ex = ehfx
1101
1102 ! *** Add Core-Hamiltonian-Matrix ***
1103 DO ispin = 1, nspins
1104 DO img = 1, nimages
1105 CALL dbcsr_add(matrix_ks(ispin, img)%matrix, matrix_h(1, img)%matrix, &
1106 1.0_dp, 1.0_dp)
1107 END DO
1108 END DO
1109 IF (use_virial .AND. calculate_forces) THEN
1110 virial%pv_exx = virial%pv_exx - virial%pv_fock_4c
1111 virial%pv_virial = virial%pv_virial - virial%pv_fock_4c
1112 virial%pv_calculate = .false.
1113 END IF
1114
1115 !update the hfx aux_fit matrix
1116 IF (dft_control%do_admm) THEN
1117 DO ispin = 1, nspins
1118 DO img = 1, nimages
1119 CALL dbcsr_add(matrix_ks_aux_fit_hfx_kp(ispin, img)%matrix, matrix_ks_aux_fit_kp(ispin, img)%matrix, &
1120 0.0_dp, 1.0_dp)
1121 END DO
1122 END DO
1123 END IF
1124
1125 CALL timestop(handle)
1126
1127 END SUBROUTINE hfx_ks_matrix_kp
1128
1129! **************************************************************************************************
1130!> \brief Add the hfx contributions to the Hamiltonian
1131!>
1132!> \param qs_env ...
1133!> \param matrix_ks ...
1134!> \param rho ...
1135!> \param energy ...
1136!> \param calculate_forces ...
1137!> \param just_energy ...
1138!> \param v_rspace_new ...
1139!> \param v_tau_rspace ...
1140!> \param ext_xc_section ...
1141!> \par History
1142!> refactoring 03-2011 [MI]
1143! **************************************************************************************************
1144
1145 SUBROUTINE hfx_ks_matrix(qs_env, matrix_ks, rho, energy, calculate_forces, &
1146 just_energy, v_rspace_new, v_tau_rspace, ext_xc_section)
1147
1148 TYPE(qs_environment_type), POINTER :: qs_env
1149 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks
1150 TYPE(qs_rho_type), POINTER :: rho
1151 TYPE(qs_energy_type), POINTER :: energy
1152 LOGICAL, INTENT(in) :: calculate_forces, just_energy
1153 TYPE(pw_r3d_rs_type), DIMENSION(:), POINTER :: v_rspace_new, v_tau_rspace
1154 TYPE(section_vals_type), OPTIONAL, POINTER :: ext_xc_section
1155
1156 CHARACTER(LEN=*), PARAMETER :: routinen = 'hfx_ks_matrix'
1157
1158 INTEGER :: handle, img, irep, ispin, mspin, &
1159 n_rep_hf, nimages, ns, nspins
1160 LOGICAL :: distribute_fock_matrix, &
1161 do_adiabatic_rescaling, &
1162 hfx_treat_lsd_in_core, &
1163 s_mstruct_changed, use_virial
1164 REAL(dp) :: eh1, ehfx, ehfxrt, eold
1165 REAL(dp), ALLOCATABLE, DIMENSION(:) :: hf_energy
1166 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks_1d, matrix_ks_aux_fit, &
1167 matrix_ks_aux_fit_hfx, matrix_ks_aux_fit_im, matrix_ks_im, rho_ao_1d, rho_ao_resp
1168 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_h, matrix_h_im, matrix_ks_orb, &
1169 rho_ao_orb
1170 TYPE(dft_control_type), POINTER :: dft_control
1171 TYPE(hfx_type), DIMENSION(:, :), POINTER :: x_data
1172 TYPE(mo_set_type), DIMENSION(:), POINTER :: mo_array
1173 TYPE(mp_para_env_type), POINTER :: para_env
1174 TYPE(pw_env_type), POINTER :: pw_env
1175 TYPE(pw_poisson_type), POINTER :: poisson_env
1176 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
1177 TYPE(qs_rho_type), POINTER :: rho_orb
1178 TYPE(rt_prop_type), POINTER :: rtp
1179 TYPE(section_vals_type), POINTER :: adiabatic_rescaling_section, &
1180 hfx_sections, input
1181 TYPE(virial_type), POINTER :: virial
1182
1183 CALL timeset(routinen, handle)
1184
1185 NULLIFY (auxbas_pw_pool, dft_control, hfx_sections, input, &
1186 para_env, poisson_env, pw_env, virial, matrix_ks_im, &
1187 matrix_ks_orb, rho_ao_orb, matrix_h, matrix_h_im, matrix_ks_aux_fit, &
1188 matrix_ks_aux_fit_im, matrix_ks_aux_fit_hfx)
1189
1190 CALL get_qs_env(qs_env=qs_env, &
1191 dft_control=dft_control, &
1192 input=input, &
1193 matrix_h_kp=matrix_h, &
1194 matrix_h_im_kp=matrix_h_im, &
1195 para_env=para_env, &
1196 pw_env=pw_env, &
1197 virial=virial, &
1198 matrix_ks_im=matrix_ks_im, &
1199 s_mstruct_changed=s_mstruct_changed, &
1200 x_data=x_data)
1201
1202 IF (dft_control%do_admm) THEN
1203 CALL get_admm_env(qs_env%admm_env, mos_aux_fit=mo_array, matrix_ks_aux_fit=matrix_ks_aux_fit, &
1204 matrix_ks_aux_fit_im=matrix_ks_aux_fit_im, matrix_ks_aux_fit_hfx=matrix_ks_aux_fit_hfx)
1205 ELSE
1206 CALL get_qs_env(qs_env=qs_env, mos=mo_array)
1207 END IF
1208
1209 nspins = dft_control%nspins
1210 nimages = dft_control%nimages
1211
1212 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
1213
1214 IF (use_virial .AND. calculate_forces) virial%pv_fock_4c = 0.0_dp
1215
1216 hfx_sections => section_vals_get_subs_vals(input, "DFT%XC%HF")
1217 IF (PRESENT(ext_xc_section)) hfx_sections => section_vals_get_subs_vals(ext_xc_section, "HF")
1218
1219 CALL section_vals_get(hfx_sections, n_repetition=n_rep_hf)
1220 CALL section_vals_val_get(hfx_sections, "TREAT_LSD_IN_CORE", l_val=hfx_treat_lsd_in_core, &
1221 i_rep_section=1)
1222 adiabatic_rescaling_section => section_vals_get_subs_vals(input, "DFT%XC%ADIABATIC_RESCALING")
1223 CALL section_vals_get(adiabatic_rescaling_section, explicit=do_adiabatic_rescaling)
1224
1225 ! *** Initialize the auxiliary ks matrix to zero if required
1226 IF (dft_control%do_admm) THEN
1227 DO ispin = 1, nspins
1228 CALL dbcsr_set(matrix_ks_aux_fit(ispin)%matrix, 0.0_dp)
1229 END DO
1230 END IF
1231 DO ispin = 1, nspins
1232 DO img = 1, nimages
1233 CALL dbcsr_set(matrix_ks(ispin, img)%matrix, 0.0_dp)
1234 END DO
1235 END DO
1236
1237 CALL section_vals_get(hfx_sections, n_repetition=n_rep_hf)
1238
1239 ALLOCATE (hf_energy(n_rep_hf))
1240
1241 eold = 0.0_dp
1242
1243 DO irep = 1, n_rep_hf
1244 ! Remember: Vhfx is added, energy is calclulated from total Vhfx,
1245 ! so energy of last iteration is correct
1246
1247 IF (do_adiabatic_rescaling .AND. hfx_treat_lsd_in_core) THEN
1248 cpabort("HFX_TREAT_LSD_IN_CORE not implemented for adiabatically rescaled hybrids")
1249 END IF
1250 ! everything is calculated with adiabatic rescaling but the potential is not added in a first step
1251 distribute_fock_matrix = .NOT. do_adiabatic_rescaling
1252
1253 mspin = 1
1254 IF (hfx_treat_lsd_in_core) mspin = nspins
1255
1256 ! fetch the correct matrices for normal HFX or ADMM
1257 IF (dft_control%do_admm) THEN
1258 CALL get_admm_env(qs_env%admm_env, matrix_ks_aux_fit=matrix_ks_1d, rho_aux_fit=rho_orb)
1259 ns = SIZE(matrix_ks_1d)
1260 matrix_ks_orb(1:ns, 1:1) => matrix_ks_1d(1:ns)
1261 ELSE
1262 CALL get_qs_env(qs_env=qs_env, matrix_ks_kp=matrix_ks_orb, rho=rho_orb)
1263 END IF
1264 CALL qs_rho_get(rho_struct=rho_orb, rho_ao_kp=rho_ao_orb)
1265 ! Finally the real hfx calulation
1266 ehfx = 0.0_dp
1267
1268 IF (x_data(irep, 1)%do_hfx_ri) THEN
1269
1270 CALL hfx_ri_update_ks(qs_env, x_data(irep, 1)%ri_data, matrix_ks_orb, ehfx, &
1271 mo_array, rho_ao_orb, &
1272 s_mstruct_changed, nspins, &
1273 x_data(irep, 1)%general_parameter%fraction)
1274 IF (dft_control%do_admm) THEN
1275 !for ADMMS, we need the exchange matrix k(d) for both spins
1276 DO ispin = 1, nspins
1277 CALL dbcsr_copy(matrix_ks_aux_fit_hfx(ispin)%matrix, matrix_ks_orb(ispin, 1)%matrix, &
1278 name="HF exch. part of matrix_ks_aux_fit for ADMMS")
1279 END DO
1280 END IF
1281
1282 ELSE
1283
1284 DO ispin = 1, mspin
1285 CALL integrate_four_center(qs_env, x_data, matrix_ks_orb, eh1, rho_ao_orb, hfx_sections, &
1286 para_env, s_mstruct_changed, irep, distribute_fock_matrix, &
1287 ispin=ispin)
1288 ehfx = ehfx + eh1
1289 END DO
1290 END IF
1291
1292 IF (calculate_forces .AND. .NOT. do_adiabatic_rescaling) THEN
1293 !Scale auxiliary density matrix for ADMMP (see Merlot2014) with gsi(ispin) to scale force
1294 IF (dft_control%do_admm) THEN
1295 CALL scale_dm(qs_env, rho_ao_orb, scale_back=.false.)
1296 END IF
1297 NULLIFY (rho_ao_resp)
1298
1299 IF (x_data(irep, 1)%do_hfx_ri) THEN
1300
1301 CALL hfx_ri_update_forces(qs_env, x_data(irep, 1)%ri_data, nspins, &
1302 x_data(irep, 1)%general_parameter%fraction, &
1303 rho_ao=rho_ao_orb, mos=mo_array, &
1304 rho_ao_resp=rho_ao_resp, &
1305 use_virial=use_virial)
1306
1307 ELSE
1308
1309 CALL derivatives_four_center(qs_env, rho_ao_orb, rho_ao_resp, hfx_sections, &
1310 para_env, irep, use_virial)
1311
1312 END IF
1313
1314 !Scale auxiliary density matrix for ADMMP back with 1/gsi(ispin)
1315 IF (dft_control%do_admm) THEN
1316 CALL scale_dm(qs_env, rho_ao_orb, scale_back=.true.)
1317 END IF
1318 END IF
1319
1320 !! If required, the calculation of the forces will be done later with adiabatic rescaling
1321 IF (do_adiabatic_rescaling) hf_energy(irep) = ehfx
1322
1323 ! special case RTP/EMD we have a full complex density and HFX has a contribution from the imaginary part
1324 ehfxrt = 0.0_dp
1325 IF (qs_env%run_rtp) THEN
1326
1327 CALL get_qs_env(qs_env=qs_env, rtp=rtp)
1328 DO ispin = 1, nspins
1329 CALL dbcsr_set(matrix_ks_im(ispin)%matrix, 0.0_dp)
1330 END DO
1331 IF (dft_control%do_admm) THEN
1332 ! matrix_ks_orb => matrix_ks_aux_fit_im
1333 ns = SIZE(matrix_ks_aux_fit_im)
1334 matrix_ks_orb(1:ns, 1:1) => matrix_ks_aux_fit_im(1:ns)
1335 DO ispin = 1, nspins
1336 CALL dbcsr_set(matrix_ks_aux_fit_im(ispin)%matrix, 0.0_dp)
1337 END DO
1338 ELSE
1339 ! matrix_ks_orb => matrix_ks_im
1340 ns = SIZE(matrix_ks_im)
1341 matrix_ks_orb(1:ns, 1:1) => matrix_ks_im(1:ns)
1342 END IF
1343
1344 CALL qs_rho_get(rho_orb, rho_ao_im=rho_ao_1d)
1345 ns = SIZE(rho_ao_1d)
1346 rho_ao_orb(1:ns, 1:1) => rho_ao_1d(1:ns)
1347
1348 ehfxrt = 0.0_dp
1349
1350 IF (x_data(irep, 1)%do_hfx_ri) THEN
1351 CALL hfx_ri_update_ks(qs_env, x_data(irep, 1)%ri_data, matrix_ks_orb, ehfx, &
1352 mo_array, rho_ao_orb, &
1353 .false., nspins, &
1354 x_data(irep, 1)%general_parameter%fraction)
1355 IF (dft_control%do_admm) THEN
1356 !for ADMMS, we need the exchange matrix k(d) for both spins
1357 DO ispin = 1, nspins
1358 CALL dbcsr_copy(matrix_ks_aux_fit_hfx(ispin)%matrix, matrix_ks_orb(ispin, 1)%matrix, &
1359 name="HF exch. part of matrix_ks_aux_fit for ADMMS")
1360 END DO
1361 END IF
1362
1363 ELSE
1364 DO ispin = 1, mspin
1365 CALL integrate_four_center(qs_env, x_data, matrix_ks_orb, eh1, rho_ao_orb, hfx_sections, &
1366 para_env, .false., irep, distribute_fock_matrix, &
1367 ispin=ispin)
1368 ehfxrt = ehfxrt + eh1
1369 END DO
1370 END IF
1371
1372 IF (calculate_forces .AND. .NOT. do_adiabatic_rescaling) THEN
1373 NULLIFY (rho_ao_resp)
1374
1375 IF (x_data(irep, 1)%do_hfx_ri) THEN
1376
1377 CALL hfx_ri_update_forces(qs_env, x_data(irep, 1)%ri_data, nspins, &
1378 x_data(irep, 1)%general_parameter%fraction, &
1379 rho_ao=rho_ao_orb, mos=mo_array, &
1380 use_virial=use_virial)
1381
1382 ELSE
1383 CALL derivatives_four_center(qs_env, rho_ao_orb, rho_ao_resp, hfx_sections, &
1384 para_env, irep, use_virial)
1385 END IF
1386 END IF
1387
1388 !! If required, the calculation of the forces will be done later with adiabatic rescaling
1389 IF (do_adiabatic_rescaling) hf_energy(irep) = ehfx + ehfxrt
1390
1391 IF (dft_control%rtp_control%velocity_gauge) THEN
1392 cpassert(ASSOCIATED(matrix_h_im))
1393 DO ispin = 1, nspins
1394 CALL dbcsr_add(matrix_ks_im(ispin)%matrix, matrix_h_im(1, 1)%matrix, &
1395 1.0_dp, 1.0_dp)
1396 END DO
1397 END IF
1398
1399 END IF
1400
1401 IF (.NOT. qs_env%run_rtp) THEN
1402 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, &
1403 poisson_env=poisson_env)
1404 eh1 = ehfx - eold
1405 CALL pw_hfx(qs_env, eh1, hfx_sections, poisson_env, auxbas_pw_pool, irep)
1406 eold = ehfx
1407 END IF
1408
1409 END DO
1410
1411 ! *** Set the total HFX energy
1412 energy%ex = ehfx + ehfxrt
1413
1414 ! *** Add Core-Hamiltonian-Matrix ***
1415 DO ispin = 1, nspins
1416 DO img = 1, nimages
1417 CALL dbcsr_add(matrix_ks(ispin, img)%matrix, matrix_h(1, img)%matrix, &
1418 1.0_dp, 1.0_dp)
1419 END DO
1420 END DO
1421 IF (use_virial .AND. calculate_forces) THEN
1422 virial%pv_exx = virial%pv_exx - virial%pv_fock_4c
1423 virial%pv_virial = virial%pv_virial - virial%pv_fock_4c
1424 virial%pv_calculate = .false.
1425 END IF
1426
1427 !! If we perform adiabatic rescaling we are now able to rescale the xc-potential
1428 IF (do_adiabatic_rescaling) THEN
1429 CALL rescale_xc_potential(qs_env, matrix_ks, rho, energy, v_rspace_new, v_tau_rspace, &
1430 hf_energy, just_energy, calculate_forces, use_virial)
1431 END IF ! do_adiabatic_rescaling
1432
1433 !update the hfx aux_fit matrixIF (dft_control%do_admm) THEN
1434 IF (dft_control%do_admm) THEN
1435 DO ispin = 1, nspins
1436 CALL dbcsr_add(matrix_ks_aux_fit_hfx(ispin)%matrix, matrix_ks_aux_fit(ispin)%matrix, &
1437 0.0_dp, 1.0_dp)
1438 END DO
1439 END IF
1440
1441 CALL timestop(handle)
1442
1443 END SUBROUTINE hfx_ks_matrix
1444
1445! **************************************************************************************************
1446!> \brief This routine modifies the xc section depending on the potential type
1447!> used for the HF exchange and the resulting correction term. Currently
1448!> three types of corrections are implemented:
1449!>
1450!> coulomb: Ex,hf = Ex,hf' + (PBEx-PBEx')
1451!> shortrange: Ex,hf = Ex,hf' + (XWPBEX-XWPBEX')
1452!> truncated: Ex,hf = Ex,hf' + ( (XWPBEX0-PBE_HOLE_TC_LR) -(XWPBEX0-PBE_HOLE_TC_LR)' )
1453!>
1454!> with ' denoting the auxiliary basis set and
1455!>
1456!> PBEx: PBE exchange functional
1457!> XWPBEX: PBE exchange hole for short-range potential (erfc(omega*r)/r)
1458!> XWPBEX0: PBE exchange hole for standard coulomb potential
1459!> PBE_HOLE_TC_LR: PBE exchange hole for longrange truncated coulomb potential
1460!>
1461!> Above explanation is correct for the deafult case. If a specific functional is requested
1462!> for the correction term (cfun), we get
1463!> Ex,hf = Ex,hf' + (cfun-cfun')
1464!> for all cases of operators.
1465!>
1466!> \param x_data ...
1467!> \param xc_section the original xc_section
1468!> \param admm_env the ADMM environment
1469!> \par History
1470!> 12.2009 created [Manuel Guidon]
1471!> 05.2021 simplify for case of no correction [JGH]
1472!> \author Manuel Guidon
1473! **************************************************************************************************
1474 SUBROUTINE create_admm_xc_section(x_data, xc_section, admm_env)
1475 TYPE(hfx_type), DIMENSION(:, :), POINTER :: x_data
1476 TYPE(section_vals_type), POINTER :: xc_section
1477 TYPE(admm_type), POINTER :: admm_env
1478
1479 LOGICAL, PARAMETER :: debug_functional = .false.
1480#if defined (__LIBXC)
1481 REAL(kind=dp), PARAMETER :: x_factor_c = 0.930525736349100025_dp
1482#endif
1483
1484 CHARACTER(LEN=20) :: name_x_func
1485 INTEGER :: hfx_potential_type, ifun, iounit, nfun
1486 LOGICAL :: funct_found
1487 REAL(dp) :: cutoff_radius, hfx_fraction, omega, &
1488 scale_coulomb, scale_longrange, scale_x
1489 TYPE(cp_logger_type), POINTER :: logger
1490 TYPE(section_vals_type), POINTER :: xc_fun, xc_fun_section
1491
1492 logger => cp_get_default_logger()
1493 NULLIFY (admm_env%xc_section_aux, admm_env%xc_section_primary)
1494
1495 !! ** Duplicate existing xc-section
1496 CALL section_vals_duplicate(xc_section, admm_env%xc_section_aux)
1497 CALL section_vals_duplicate(xc_section, admm_env%xc_section_primary)
1498 !** Now modify the auxiliary basis
1499 !** First remove all functionals
1500 xc_fun_section => section_vals_get_subs_vals(admm_env%xc_section_aux, "XC_FUNCTIONAL")
1501
1502 !* Overwrite possible shortcut
1503 CALL section_vals_val_set(xc_fun_section, "_SECTION_PARAMETERS_", &
1504 i_val=xc_funct_no_shortcut)
1505
1506 !** Get number of Functionals in the list
1507 ifun = 0
1508 nfun = 0
1509 DO
1510 ifun = ifun + 1
1511 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
1512 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
1513 nfun = nfun + 1
1514 END DO
1515
1516 ifun = 0
1517 DO ifun = 1, nfun
1518 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=1)
1519 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
1520 CALL section_vals_remove_values(xc_fun)
1521 END DO
1522
1523 IF (ASSOCIATED(x_data)) THEN
1524 hfx_potential_type = x_data(1, 1)%potential_parameter%potential_type
1525 hfx_fraction = x_data(1, 1)%general_parameter%fraction
1526 ELSE
1527 cpwarn("ADMM requested without a DFT%XC%HF section. It will be ignored for the SCF.")
1528 admm_env%aux_exch_func = do_admm_aux_exch_func_none
1529 END IF
1530
1531 !in case of no admm exchange corr., no auxiliary exchange functional needed
1532 IF (admm_env%aux_exch_func == do_admm_aux_exch_func_none) THEN
1533 CALL section_vals_val_set(xc_fun_section, "_SECTION_PARAMETERS_", &
1534 i_val=xc_none)
1535 hfx_fraction = 0.0_dp
1536 ELSE IF (admm_env%aux_exch_func == do_admm_aux_exch_func_default) THEN
1537 ! default PBE Functional
1538 !! ** Add functionals evaluated with auxiliary basis
1539 SELECT CASE (hfx_potential_type)
1540 CASE (do_potential_coulomb)
1541 CALL section_vals_val_set(xc_fun_section, "PBE%_SECTION_PARAMETERS_", &
1542 l_val=.true.)
1543 CALL section_vals_val_set(xc_fun_section, "PBE%SCALE_X", &
1544 r_val=-hfx_fraction)
1545 CALL section_vals_val_set(xc_fun_section, "PBE%SCALE_C", &
1546 r_val=0.0_dp)
1547 CASE (do_potential_short)
1548 omega = x_data(1, 1)%potential_parameter%omega
1549 CALL section_vals_val_set(xc_fun_section, "XWPBE%_SECTION_PARAMETERS_", &
1550 l_val=.true.)
1551 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
1552 r_val=-hfx_fraction)
1553 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
1554 r_val=0.0_dp)
1555 CALL section_vals_val_set(xc_fun_section, "XWPBE%OMEGA", &
1556 r_val=omega)
1557 CASE (do_potential_truncated)
1558 cutoff_radius = x_data(1, 1)%potential_parameter%cutoff_radius
1559 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%_SECTION_PARAMETERS_", &
1560 l_val=.true.)
1561 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
1562 r_val=hfx_fraction)
1563 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
1564 r_val=cutoff_radius)
1565 CALL section_vals_val_set(xc_fun_section, "XWPBE%_SECTION_PARAMETERS_", &
1566 l_val=.true.)
1567 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
1568 r_val=0.0_dp)
1569 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
1570 r_val=-hfx_fraction)
1571 CASE (do_potential_long)
1572 omega = x_data(1, 1)%potential_parameter%omega
1573 CALL section_vals_val_set(xc_fun_section, "XWPBE%_SECTION_PARAMETERS_", &
1574 l_val=.true.)
1575 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
1576 r_val=hfx_fraction)
1577 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
1578 r_val=-hfx_fraction)
1579 CALL section_vals_val_set(xc_fun_section, "XWPBE%OMEGA", &
1580 r_val=omega)
1581 CASE (do_potential_mix_cl)
1582 omega = x_data(1, 1)%potential_parameter%omega
1583 scale_coulomb = x_data(1, 1)%potential_parameter%scale_coulomb
1584 scale_longrange = x_data(1, 1)%potential_parameter%scale_longrange
1585 CALL section_vals_val_set(xc_fun_section, "XWPBE%_SECTION_PARAMETERS_", &
1586 l_val=.true.)
1587 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
1588 r_val=hfx_fraction*scale_longrange)
1589 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
1590 r_val=-hfx_fraction*(scale_longrange + scale_coulomb))
1591 CALL section_vals_val_set(xc_fun_section, "XWPBE%OMEGA", &
1592 r_val=omega)
1593 CASE (do_potential_mix_cl_trunc)
1594 omega = x_data(1, 1)%potential_parameter%omega
1595 cutoff_radius = x_data(1, 1)%potential_parameter%cutoff_radius
1596 scale_coulomb = x_data(1, 1)%potential_parameter%scale_coulomb
1597 scale_longrange = x_data(1, 1)%potential_parameter%scale_longrange
1598 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%_SECTION_PARAMETERS_", &
1599 l_val=.true.)
1600 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
1601 r_val=hfx_fraction*(scale_longrange + scale_coulomb))
1602 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
1603 r_val=cutoff_radius)
1604 CALL section_vals_val_set(xc_fun_section, "XWPBE%_SECTION_PARAMETERS_", &
1605 l_val=.true.)
1606 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
1607 r_val=hfx_fraction*scale_longrange)
1608 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
1609 r_val=-hfx_fraction*(scale_longrange + scale_coulomb))
1610 CALL section_vals_val_set(xc_fun_section, "XWPBE%OMEGA", &
1611 r_val=omega)
1612 CASE DEFAULT
1613 cpabort("Unknown potential operator!")
1614 END SELECT
1615
1616 !** Now modify the functionals for the primary basis
1617 xc_fun_section => section_vals_get_subs_vals(admm_env%xc_section_primary, "XC_FUNCTIONAL")
1618 !* Overwrite possible shortcut
1619 CALL section_vals_val_set(xc_fun_section, "_SECTION_PARAMETERS_", &
1620 i_val=xc_funct_no_shortcut)
1621
1622 SELECT CASE (hfx_potential_type)
1623 CASE (do_potential_coulomb)
1624 ifun = 0
1625 funct_found = .false.
1626 DO
1627 ifun = ifun + 1
1628 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
1629 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
1630 IF (xc_fun%section%name == "PBE") THEN
1631 funct_found = .true.
1632 END IF
1633 END DO
1634 IF (.NOT. funct_found) THEN
1635 CALL section_vals_val_set(xc_fun_section, "PBE%_SECTION_PARAMETERS_", &
1636 l_val=.true.)
1637 CALL section_vals_val_set(xc_fun_section, "PBE%SCALE_X", &
1638 r_val=hfx_fraction)
1639 CALL section_vals_val_set(xc_fun_section, "PBE%SCALE_C", &
1640 r_val=0.0_dp)
1641 ELSE
1642 CALL section_vals_val_get(xc_fun_section, "PBE%SCALE_X", &
1643 r_val=scale_x)
1644 scale_x = scale_x + hfx_fraction
1645 CALL section_vals_val_set(xc_fun_section, "PBE%SCALE_X", &
1646 r_val=scale_x)
1647 END IF
1648 CASE (do_potential_short)
1649 omega = x_data(1, 1)%potential_parameter%omega
1650 ifun = 0
1651 funct_found = .false.
1652 DO
1653 ifun = ifun + 1
1654 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
1655 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
1656 IF (xc_fun%section%name == "XWPBE") THEN
1657 funct_found = .true.
1658 END IF
1659 END DO
1660 IF (.NOT. funct_found) THEN
1661 CALL section_vals_val_set(xc_fun_section, "XWPBE%_SECTION_PARAMETERS_", &
1662 l_val=.true.)
1663 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
1664 r_val=hfx_fraction)
1665 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
1666 r_val=0.0_dp)
1667 CALL section_vals_val_set(xc_fun_section, "XWPBE%OMEGA", &
1668 r_val=omega)
1669 ELSE
1670 CALL section_vals_val_get(xc_fun_section, "XWPBE%SCALE_X", &
1671 r_val=scale_x)
1672 scale_x = scale_x + hfx_fraction
1673 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
1674 r_val=scale_x)
1675 END IF
1676 CASE (do_potential_long)
1677 omega = x_data(1, 1)%potential_parameter%omega
1678 ifun = 0
1679 funct_found = .false.
1680 DO
1681 ifun = ifun + 1
1682 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
1683 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
1684 IF (xc_fun%section%name == "XWPBE") THEN
1685 funct_found = .true.
1686 END IF
1687 END DO
1688 IF (.NOT. funct_found) THEN
1689 CALL section_vals_val_set(xc_fun_section, "XWPBE%_SECTION_PARAMETERS_", &
1690 l_val=.true.)
1691 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
1692 r_val=-hfx_fraction)
1693 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
1694 r_val=hfx_fraction)
1695 CALL section_vals_val_set(xc_fun_section, "XWPBE%OMEGA", &
1696 r_val=omega)
1697 ELSE
1698 CALL section_vals_val_get(xc_fun_section, "XWPBE%SCALE_X", &
1699 r_val=scale_x)
1700 scale_x = scale_x - hfx_fraction
1701 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
1702 r_val=scale_x)
1703 CALL section_vals_val_get(xc_fun_section, "XWPBE%SCALE_X0", &
1704 r_val=scale_x)
1705 scale_x = scale_x + hfx_fraction
1706 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
1707 r_val=scale_x)
1708
1709 CALL section_vals_val_set(xc_fun_section, "XWPBE%OMEGA", &
1710 r_val=omega)
1711 END IF
1712 CASE (do_potential_truncated)
1713 cutoff_radius = x_data(1, 1)%potential_parameter%cutoff_radius
1714 ifun = 0
1715 funct_found = .false.
1716 DO
1717 ifun = ifun + 1
1718 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
1719 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
1720 IF (xc_fun%section%name == "PBE_HOLE_T_C_LR") THEN
1721 funct_found = .true.
1722 END IF
1723 END DO
1724 IF (.NOT. funct_found) THEN
1725 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%_SECTION_PARAMETERS_", &
1726 l_val=.true.)
1727 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
1728 r_val=-hfx_fraction)
1729 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
1730 r_val=cutoff_radius)
1731 ELSE
1732 CALL section_vals_val_get(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
1733 r_val=scale_x)
1734 scale_x = scale_x - hfx_fraction
1735 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
1736 r_val=scale_x)
1737 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
1738 r_val=cutoff_radius)
1739 END IF
1740 ifun = 0
1741 funct_found = .false.
1742 DO
1743 ifun = ifun + 1
1744 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
1745 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
1746 IF (xc_fun%section%name == "XWPBE") THEN
1747 funct_found = .true.
1748 END IF
1749 END DO
1750 IF (.NOT. funct_found) THEN
1751 CALL section_vals_val_set(xc_fun_section, "XWPBE%_SECTION_PARAMETERS_", &
1752 l_val=.true.)
1753 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
1754 r_val=hfx_fraction)
1755 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
1756 r_val=0.0_dp)
1757
1758 ELSE
1759 CALL section_vals_val_get(xc_fun_section, "XWPBE%SCALE_X0", &
1760 r_val=scale_x)
1761 scale_x = scale_x + hfx_fraction
1762 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
1763 r_val=scale_x)
1764 END IF
1765 CASE (do_potential_mix_cl_trunc)
1766 cutoff_radius = x_data(1, 1)%potential_parameter%cutoff_radius
1767 omega = x_data(1, 1)%potential_parameter%omega
1768 scale_coulomb = x_data(1, 1)%potential_parameter%scale_coulomb
1769 scale_longrange = x_data(1, 1)%potential_parameter%scale_longrange
1770 ifun = 0
1771 funct_found = .false.
1772 DO
1773 ifun = ifun + 1
1774 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
1775 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
1776 IF (xc_fun%section%name == "PBE_HOLE_T_C_LR") THEN
1777 funct_found = .true.
1778 END IF
1779 END DO
1780 IF (.NOT. funct_found) THEN
1781 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%_SECTION_PARAMETERS_", &
1782 l_val=.true.)
1783 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
1784 r_val=-hfx_fraction*(scale_coulomb + scale_longrange))
1785 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
1786 r_val=cutoff_radius)
1787
1788 ELSE
1789 CALL section_vals_val_get(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
1790 r_val=scale_x)
1791 scale_x = scale_x - hfx_fraction*(scale_coulomb + scale_longrange)
1792 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
1793 r_val=scale_x)
1794 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
1795 r_val=cutoff_radius)
1796 END IF
1797 ifun = 0
1798 funct_found = .false.
1799 DO
1800 ifun = ifun + 1
1801 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
1802 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
1803 IF (xc_fun%section%name == "XWPBE") THEN
1804 funct_found = .true.
1805 END IF
1806 END DO
1807 IF (.NOT. funct_found) THEN
1808 CALL section_vals_val_set(xc_fun_section, "XWPBE%_SECTION_PARAMETERS_", &
1809 l_val=.true.)
1810 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
1811 r_val=hfx_fraction*(scale_coulomb + scale_longrange))
1812 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
1813 r_val=-hfx_fraction*scale_longrange)
1814 CALL section_vals_val_set(xc_fun_section, "XWPBE%OMEGA", &
1815 r_val=omega)
1816
1817 ELSE
1818 CALL section_vals_val_get(xc_fun_section, "XWPBE%SCALE_X0", &
1819 r_val=scale_x)
1820 scale_x = scale_x + hfx_fraction*(scale_coulomb + scale_longrange)
1821 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
1822 r_val=scale_x)
1823 CALL section_vals_val_get(xc_fun_section, "XWPBE%SCALE_X", &
1824 r_val=scale_x)
1825 scale_x = scale_x - hfx_fraction*scale_longrange
1826 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
1827 r_val=scale_x)
1828
1829 CALL section_vals_val_set(xc_fun_section, "XWPBE%OMEGA", &
1830 r_val=omega)
1831 END IF
1832 CASE (do_potential_mix_cl)
1833 omega = x_data(1, 1)%potential_parameter%omega
1834 scale_coulomb = x_data(1, 1)%potential_parameter%scale_coulomb
1835 scale_longrange = x_data(1, 1)%potential_parameter%scale_longrange
1836 ifun = 0
1837 funct_found = .false.
1838 DO
1839 ifun = ifun + 1
1840 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
1841 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
1842 IF (xc_fun%section%name == "XWPBE") THEN
1843 funct_found = .true.
1844 END IF
1845 END DO
1846 IF (.NOT. funct_found) THEN
1847 CALL section_vals_val_set(xc_fun_section, "XWPBE%_SECTION_PARAMETERS_", &
1848 l_val=.true.)
1849 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
1850 r_val=hfx_fraction*(scale_coulomb + scale_longrange))
1851 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
1852 r_val=-hfx_fraction*scale_longrange)
1853 CALL section_vals_val_set(xc_fun_section, "XWPBE%OMEGA", &
1854 r_val=omega)
1855
1856 ELSE
1857 CALL section_vals_val_get(xc_fun_section, "XWPBE%SCALE_X0", &
1858 r_val=scale_x)
1859 scale_x = scale_x + hfx_fraction*(scale_coulomb + scale_longrange)
1860 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X0", &
1861 r_val=scale_x)
1862
1863 CALL section_vals_val_get(xc_fun_section, "XWPBE%SCALE_X", &
1864 r_val=scale_x)
1865 scale_x = scale_x - hfx_fraction*scale_longrange
1866 CALL section_vals_val_set(xc_fun_section, "XWPBE%SCALE_X", &
1867 r_val=scale_x)
1868
1869 CALL section_vals_val_set(xc_fun_section, "XWPBE%OMEGA", &
1870 r_val=omega)
1871 END IF
1872 END SELECT
1873 ELSE IF (admm_env%aux_exch_func == do_admm_aux_exch_func_default_libxc) THEN
1874 ! default PBE Functional
1875 !! ** Add functionals evaluated with auxiliary basis
1876#if defined (__LIBXC)
1877 SELECT CASE (hfx_potential_type)
1878 CASE (do_potential_coulomb)
1879 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%_SECTION_PARAMETERS_", &
1880 l_val=.true.)
1881 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
1882 r_val=-hfx_fraction)
1883 CASE (do_potential_short)
1884 omega = x_data(1, 1)%potential_parameter%omega
1885 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_SECTION_PARAMETERS_", &
1886 l_val=.true.)
1887 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
1888 r_val=-hfx_fraction)
1889 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_OMEGA", &
1890 r_val=omega)
1891 CASE (do_potential_truncated)
1892 cutoff_radius = x_data(1, 1)%potential_parameter%cutoff_radius
1893 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%_SECTION_PARAMETERS_", &
1894 l_val=.true.)
1895 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
1896 r_val=hfx_fraction)
1897 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
1898 r_val=cutoff_radius)
1899 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_SECTION_PARAMETERS_", &
1900 l_val=.true.)
1901 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
1902 r_val=-hfx_fraction)
1903 CASE (do_potential_long)
1904 omega = x_data(1, 1)%potential_parameter%omega
1905 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_SECTION_PARAMETERS_", &
1906 l_val=.true.)
1907 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
1908 r_val=hfx_fraction)
1909 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_OMEGA", &
1910 r_val=omega)
1911 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%_SECTION_PARAMETERS_", &
1912 l_val=.true.)
1913 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
1914 r_val=-hfx_fraction)
1915 CASE (do_potential_mix_cl)
1916 omega = x_data(1, 1)%potential_parameter%omega
1917 scale_coulomb = x_data(1, 1)%potential_parameter%scale_coulomb
1918 scale_longrange = x_data(1, 1)%potential_parameter%scale_longrange
1919 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_SECTION_PARAMETERS_", &
1920 l_val=.true.)
1921 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
1922 r_val=hfx_fraction*scale_longrange)
1923 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_OMEGA", &
1924 r_val=omega)
1925 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%_SECTION_PARAMETERS_", &
1926 l_val=.true.)
1927 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
1928 r_val=-hfx_fraction*(scale_longrange + scale_coulomb))
1929 CASE (do_potential_mix_cl_trunc)
1930 omega = x_data(1, 1)%potential_parameter%omega
1931 cutoff_radius = x_data(1, 1)%potential_parameter%cutoff_radius
1932 scale_coulomb = x_data(1, 1)%potential_parameter%scale_coulomb
1933 scale_longrange = x_data(1, 1)%potential_parameter%scale_longrange
1934 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%_SECTION_PARAMETERS_", &
1935 l_val=.true.)
1936 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
1937 r_val=hfx_fraction*(scale_longrange + scale_coulomb))
1938 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
1939 r_val=cutoff_radius)
1940 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_SECTION_PARAMETERS_", &
1941 l_val=.true.)
1942 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
1943 r_val=hfx_fraction*scale_longrange)
1944 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_OMEGA", &
1945 r_val=omega)
1946 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%_SECTION_PARAMETERS_", &
1947 l_val=.true.)
1948 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
1949 r_val=-hfx_fraction*(scale_longrange + scale_coulomb))
1950 CASE DEFAULT
1951 cpabort("Unknown potential operator!")
1952 END SELECT
1953
1954 !** Now modify the functionals for the primary basis
1955 xc_fun_section => section_vals_get_subs_vals(admm_env%xc_section_primary, "XC_FUNCTIONAL")
1956 !* Overwrite possible shortcut
1957 CALL section_vals_val_set(xc_fun_section, "_SECTION_PARAMETERS_", &
1958 i_val=xc_funct_no_shortcut)
1959
1960 SELECT CASE (hfx_potential_type)
1961 CASE (do_potential_coulomb)
1962 ifun = 0
1963 funct_found = .false.
1964 DO
1965 ifun = ifun + 1
1966 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
1967 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
1968 IF (xc_fun%section%name == "GGA_X_PBE") THEN
1969 funct_found = .true.
1970 END IF
1971 END DO
1972 IF (.NOT. funct_found) THEN
1973 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%_SECTION_PARAMETERS_", &
1974 l_val=.true.)
1975 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
1976 r_val=hfx_fraction)
1977 ELSE
1978 CALL section_vals_val_get(xc_fun_section, "GGA_X_PBE%SCALE", &
1979 r_val=scale_x)
1980 scale_x = scale_x + hfx_fraction
1981 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
1982 r_val=scale_x)
1983 END IF
1984 CASE (do_potential_short)
1985 omega = x_data(1, 1)%potential_parameter%omega
1986 ifun = 0
1987 funct_found = .false.
1988 DO
1989 ifun = ifun + 1
1990 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
1991 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
1992 IF (xc_fun%section%name == "GGA_X_WPBEH") THEN
1993 funct_found = .true.
1994 END IF
1995 END DO
1996 IF (.NOT. funct_found) THEN
1997 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_SECTION_PARAMETERS_", &
1998 l_val=.true.)
1999 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
2000 r_val=hfx_fraction)
2001 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_OMEGA", &
2002 r_val=omega)
2003 ELSE
2004 CALL section_vals_val_get(xc_fun_section, "GGA_X_WPBEH%SCALE", &
2005 r_val=scale_x)
2006 scale_x = scale_x + hfx_fraction
2007 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
2008 r_val=scale_x)
2009 END IF
2010 CASE (do_potential_long)
2011 omega = x_data(1, 1)%potential_parameter%omega
2012 ifun = 0
2013 funct_found = .false.
2014 DO
2015 ifun = ifun + 1
2016 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
2017 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
2018 IF (xc_fun%section%name == "GGA_X_WPBEH") THEN
2019 funct_found = .true.
2020 END IF
2021 END DO
2022 IF (.NOT. funct_found) THEN
2023 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_SECTION_PARAMETERS_", &
2024 l_val=.true.)
2025 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
2026 r_val=-hfx_fraction)
2027 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_OMEGA", &
2028 r_val=omega)
2029 ELSE
2030 CALL section_vals_val_get(xc_fun_section, "GGA_X_WPBEH%SCALE", &
2031 r_val=scale_x)
2032 scale_x = scale_x - hfx_fraction
2033 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
2034 r_val=scale_x)
2035
2036 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_OMEGA", &
2037 r_val=omega)
2038 END IF
2039 ifun = 0
2040 funct_found = .false.
2041 DO
2042 ifun = ifun + 1
2043 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
2044 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
2045 IF (xc_fun%section%name == "GGA_X_PBE") THEN
2046 funct_found = .true.
2047 END IF
2048 END DO
2049 IF (.NOT. funct_found) THEN
2050 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%_SECTION_PARAMETERS_", &
2051 l_val=.true.)
2052 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
2053 r_val=hfx_fraction)
2054 ELSE
2055 CALL section_vals_val_get(xc_fun_section, "GGA_X_PBE%SCALE", &
2056 r_val=scale_x)
2057 scale_x = scale_x + hfx_fraction
2058 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
2059 r_val=scale_x)
2060 END IF
2061 CASE (do_potential_truncated)
2062 cutoff_radius = x_data(1, 1)%potential_parameter%cutoff_radius
2063 ifun = 0
2064 funct_found = .false.
2065 DO
2066 ifun = ifun + 1
2067 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
2068 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
2069 IF (xc_fun%section%name == "PBE_HOLE_T_C_LR") THEN
2070 funct_found = .true.
2071 END IF
2072 END DO
2073 IF (.NOT. funct_found) THEN
2074 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%_SECTION_PARAMETERS_", &
2075 l_val=.true.)
2076 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
2077 r_val=-hfx_fraction)
2078 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
2079 r_val=cutoff_radius)
2080
2081 ELSE
2082 CALL section_vals_val_get(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
2083 r_val=scale_x)
2084 scale_x = scale_x - hfx_fraction
2085 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
2086 r_val=scale_x)
2087 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
2088 r_val=cutoff_radius)
2089 END IF
2090 ifun = 0
2091 funct_found = .false.
2092 DO
2093 ifun = ifun + 1
2094 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
2095 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
2096 IF (xc_fun%section%name == "GGA_X_PBE") THEN
2097 funct_found = .true.
2098 END IF
2099 END DO
2100 IF (.NOT. funct_found) THEN
2101 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%_SECTION_PARAMETERS_", &
2102 l_val=.true.)
2103 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
2104 r_val=hfx_fraction)
2105
2106 ELSE
2107 CALL section_vals_val_get(xc_fun_section, "GGA_X_PBE%SCALE", &
2108 r_val=scale_x)
2109 scale_x = scale_x + hfx_fraction
2110 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
2111 r_val=scale_x)
2112 END IF
2113 CASE (do_potential_mix_cl_trunc)
2114 cutoff_radius = x_data(1, 1)%potential_parameter%cutoff_radius
2115 omega = x_data(1, 1)%potential_parameter%omega
2116 scale_coulomb = x_data(1, 1)%potential_parameter%scale_coulomb
2117 scale_longrange = x_data(1, 1)%potential_parameter%scale_longrange
2118 ifun = 0
2119 funct_found = .false.
2120 DO
2121 ifun = ifun + 1
2122 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
2123 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
2124 IF (xc_fun%section%name == "PBE_HOLE_T_C_LR") THEN
2125 funct_found = .true.
2126 END IF
2127 END DO
2128 IF (.NOT. funct_found) THEN
2129 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%_SECTION_PARAMETERS_", &
2130 l_val=.true.)
2131 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
2132 r_val=-hfx_fraction*(scale_coulomb + scale_longrange))
2133 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
2134 r_val=cutoff_radius)
2135
2136 ELSE
2137 CALL section_vals_val_get(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
2138 r_val=scale_x)
2139 scale_x = scale_x - hfx_fraction*(scale_coulomb + scale_longrange)
2140 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%SCALE_X", &
2141 r_val=scale_x)
2142 CALL section_vals_val_set(xc_fun_section, "PBE_HOLE_T_C_LR%CUTOFF_RADIUS", &
2143 r_val=cutoff_radius)
2144 END IF
2145 ifun = 0
2146 funct_found = .false.
2147 DO
2148 ifun = ifun + 1
2149 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
2150 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
2151 IF (xc_fun%section%name == "GGA_X_WPBEH") THEN
2152 funct_found = .true.
2153 END IF
2154 END DO
2155 IF (.NOT. funct_found) THEN
2156 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_SECTION_PARAMETERS_", &
2157 l_val=.true.)
2158 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
2159 r_val=-hfx_fraction*scale_longrange)
2160 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_OMEGA", &
2161 r_val=omega)
2162
2163 ELSE
2164 CALL section_vals_val_get(xc_fun_section, "GGA_X_WPBEH%SCALE", &
2165 r_val=scale_x)
2166 scale_x = scale_x - hfx_fraction*scale_longrange
2167 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
2168 r_val=scale_x)
2169
2170 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_OMEGA", &
2171 r_val=omega)
2172 END IF
2173 ifun = 0
2174 funct_found = .false.
2175 DO
2176 ifun = ifun + 1
2177 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
2178 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
2179 IF (xc_fun%section%name == "GGA_X_PBE") THEN
2180 funct_found = .true.
2181 END IF
2182 END DO
2183 IF (.NOT. funct_found) THEN
2184 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%_SECTION_PARAMETERS_", &
2185 l_val=.true.)
2186 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
2187 r_val=hfx_fraction*(scale_coulomb + scale_longrange))
2188 ELSE
2189 CALL section_vals_val_get(xc_fun_section, "GGA_X_PBE%SCALE", &
2190 r_val=scale_x)
2191 scale_x = scale_x + hfx_fraction*(scale_coulomb + scale_longrange)
2192 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
2193 r_val=scale_x)
2194 END IF
2195 CASE (do_potential_mix_cl)
2196 omega = x_data(1, 1)%potential_parameter%omega
2197 scale_coulomb = x_data(1, 1)%potential_parameter%scale_coulomb
2198 scale_longrange = x_data(1, 1)%potential_parameter%scale_longrange
2199 ifun = 0
2200 funct_found = .false.
2201 DO
2202 ifun = ifun + 1
2203 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
2204 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
2205 IF (xc_fun%section%name == "GGA_X_WPBEH") THEN
2206 funct_found = .true.
2207 END IF
2208 END DO
2209 IF (.NOT. funct_found) THEN
2210 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_SECTION_PARAMETERS_", &
2211 l_val=.true.)
2212 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
2213 r_val=-hfx_fraction*scale_longrange)
2214 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_OMEGA", &
2215 r_val=omega)
2216
2217 ELSE
2218 CALL section_vals_val_get(xc_fun_section, "GGA_X_WPBEH%SCALE", &
2219 r_val=scale_x)
2220 scale_x = scale_x - hfx_fraction*scale_longrange
2221 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%SCALE", &
2222 r_val=scale_x)
2223
2224 CALL section_vals_val_set(xc_fun_section, "GGA_X_WPBEH%_OMEGA", &
2225 r_val=omega)
2226 END IF
2227 ifun = 0
2228 funct_found = .false.
2229 DO
2230 ifun = ifun + 1
2231 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
2232 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
2233 IF (xc_fun%section%name == "GGA_X_PBE") THEN
2234 funct_found = .true.
2235 END IF
2236 END DO
2237 IF (.NOT. funct_found) THEN
2238 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%_SECTION_PARAMETERS_", &
2239 l_val=.true.)
2240 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
2241 r_val=hfx_fraction*(scale_coulomb + scale_longrange))
2242 ELSE
2243 CALL section_vals_val_get(xc_fun_section, "GGA_X_PBE%SCALE", &
2244 r_val=scale_x)
2245 scale_x = scale_x + hfx_fraction*(scale_coulomb + scale_longrange)
2246 CALL section_vals_val_set(xc_fun_section, "GGA_X_PBE%SCALE", &
2247 r_val=scale_x)
2248 END IF
2249 END SELECT
2250#else
2251 CALL cp_abort(__location__, "In order use a LibXC-based ADMM "// &
2252 "exchange correction functionals, you have to compile and link against LibXC!")
2253#endif
2254
2255 ! PBEX (always bare form), OPTX and Becke88 functional
2256 ELSE IF (admm_env%aux_exch_func == do_admm_aux_exch_func_pbex .OR. &
2257 admm_env%aux_exch_func == do_admm_aux_exch_func_opt .OR. &
2258 admm_env%aux_exch_func == do_admm_aux_exch_func_bee) THEN
2259 IF (admm_env%aux_exch_func == do_admm_aux_exch_func_pbex) THEN
2260 name_x_func = 'PBE'
2261 ELSE IF (admm_env%aux_exch_func == do_admm_aux_exch_func_opt) THEN
2262 name_x_func = 'OPTX'
2263 ELSE IF (admm_env%aux_exch_func == do_admm_aux_exch_func_bee) THEN
2264 name_x_func = 'BECKE88'
2265 END IF
2266 !primary basis
2267 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%_SECTION_PARAMETERS_", &
2268 l_val=.true.)
2269 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%SCALE_X", &
2270 r_val=-hfx_fraction)
2271
2272 IF (admm_env%aux_exch_func == do_admm_aux_exch_func_pbex) THEN
2273 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%SCALE_C", r_val=0.0_dp)
2274 END IF
2275
2276 IF (admm_env%aux_exch_func == do_admm_aux_exch_func_opt) THEN
2277 IF (admm_env%aux_exch_func_param) THEN
2278 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%A1", &
2279 r_val=admm_env%aux_x_param(1))
2280 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%A2", &
2281 r_val=admm_env%aux_x_param(2))
2282 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%GAMMA", &
2283 r_val=admm_env%aux_x_param(3))
2284 END IF
2285 END IF
2286
2287 !** Now modify the functionals for the primary basis
2288 xc_fun_section => section_vals_get_subs_vals(admm_env%xc_section_primary, "XC_FUNCTIONAL")
2289 !* Overwrite possible L")
2290 !* Overwrite possible shortcut
2291 CALL section_vals_val_set(xc_fun_section, "_SECTION_PARAMETERS_", &
2292 i_val=xc_funct_no_shortcut)
2293
2294 ifun = 0
2295 funct_found = .false.
2296 DO
2297 ifun = ifun + 1
2298 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
2299 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
2300 IF (xc_fun%section%name == trim(name_x_func)) THEN
2301 funct_found = .true.
2302 END IF
2303 END DO
2304 IF (.NOT. funct_found) THEN
2305 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%_SECTION_PARAMETERS_", &
2306 l_val=.true.)
2307 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%SCALE_X", &
2308 r_val=hfx_fraction)
2309 IF (admm_env%aux_exch_func == do_admm_aux_exch_func_pbex) THEN
2310 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%SCALE_C", &
2311 r_val=0.0_dp)
2312 ELSE IF (admm_env%aux_exch_func == do_admm_aux_exch_func_opt) THEN
2313 IF (admm_env%aux_exch_func_param) THEN
2314 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%A1", &
2315 r_val=admm_env%aux_x_param(1))
2316 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%A2", &
2317 r_val=admm_env%aux_x_param(2))
2318 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%GAMMA", &
2319 r_val=admm_env%aux_x_param(3))
2320 END IF
2321 END IF
2322
2323 ELSE
2324 CALL section_vals_val_get(xc_fun_section, trim(name_x_func)//"%SCALE_X", &
2325 r_val=scale_x)
2326 scale_x = scale_x + hfx_fraction
2327 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%SCALE_X", &
2328 r_val=scale_x)
2329 IF (admm_env%aux_exch_func == do_admm_aux_exch_func_opt) THEN
2330 cpassert(.NOT. admm_env%aux_exch_func_param)
2331 END IF
2332 END IF
2333
2334 ELSE IF (admm_env%aux_exch_func == do_admm_aux_exch_func_pbex_libxc .OR. &
2335 admm_env%aux_exch_func == do_admm_aux_exch_func_opt_libxc .OR. &
2336 admm_env%aux_exch_func == do_admm_aux_exch_func_sx_libxc .OR. &
2337 admm_env%aux_exch_func == do_admm_aux_exch_func_bee_libxc) THEN
2338#if defined(__LIBXC)
2339 IF (admm_env%aux_exch_func == do_admm_aux_exch_func_pbex_libxc) THEN
2340 name_x_func = 'GGA_X_PBE'
2341 ELSE IF (admm_env%aux_exch_func == do_admm_aux_exch_func_opt_libxc) THEN
2342 name_x_func = 'GGA_X_OPTX'
2343 ELSE IF (admm_env%aux_exch_func == do_admm_aux_exch_func_bee_libxc) THEN
2344 name_x_func = 'GGA_X_B88'
2345 ELSE IF (admm_env%aux_exch_func == do_admm_aux_exch_func_sx_libxc) THEN
2346 name_x_func = 'LDA_X'
2347 END IF
2348 !primary basis
2349 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%_SECTION_PARAMETERS_", &
2350 l_val=.true.)
2351 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%SCALE", &
2352 r_val=-hfx_fraction)
2353
2354 IF (admm_env%aux_exch_func == do_admm_aux_exch_func_opt_libxc) THEN
2355 IF (admm_env%aux_exch_func_param) THEN
2356 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%_A", &
2357 r_val=admm_env%aux_x_param(1))
2358 ! LibXC rescales the second parameter of the OPTX functional (see documentation there)
2359 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%_B", &
2360 r_val=admm_env%aux_x_param(2)/x_factor_c)
2361 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%_GAMMA", &
2362 r_val=admm_env%aux_x_param(3))
2363 END IF
2364 END IF
2365
2366 !** Now modify the functionals for the primary basis
2367 xc_fun_section => section_vals_get_subs_vals(admm_env%xc_section_primary, "XC_FUNCTIONAL")
2368 !* Overwrite possible L")
2369 !* Overwrite possible shortcut
2370 CALL section_vals_val_set(xc_fun_section, "_SECTION_PARAMETERS_", &
2371 i_val=xc_funct_no_shortcut)
2372
2373 ifun = 0
2374 funct_found = .false.
2375 DO
2376 ifun = ifun + 1
2377 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
2378 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
2379 IF (xc_fun%section%name == trim(name_x_func)) THEN
2380 funct_found = .true.
2381 END IF
2382 END DO
2383 IF (.NOT. funct_found) THEN
2384 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%_SECTION_PARAMETERS_", &
2385 l_val=.true.)
2386 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%SCALE", &
2387 r_val=hfx_fraction)
2388 IF (admm_env%aux_exch_func == do_admm_aux_exch_func_opt_libxc) THEN
2389 IF (admm_env%aux_exch_func_param) THEN
2390 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%_A", &
2391 r_val=admm_env%aux_x_param(1))
2392 ! LibXC rescales the second parameter of the OPTX functional (see documentation there)
2393 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%_B", &
2394 r_val=admm_env%aux_x_param(2)/x_factor_c)
2395 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%_GAMMA", &
2396 r_val=admm_env%aux_x_param(3))
2397 END IF
2398 END IF
2399
2400 ELSE
2401 CALL section_vals_val_get(xc_fun_section, trim(name_x_func)//"%SCALE", &
2402 r_val=scale_x)
2403 scale_x = scale_x + hfx_fraction
2404 CALL section_vals_val_set(xc_fun_section, trim(name_x_func)//"%SCALE", &
2405 r_val=scale_x)
2406 IF (admm_env%aux_exch_func == do_admm_aux_exch_func_opt_libxc) THEN
2407 cpassert(.NOT. admm_env%aux_exch_func_param)
2408 END IF
2409 END IF
2410#else
2411 CALL cp_abort(__location__, "In order use a LibXC-based ADMM "// &
2412 "exchange correction functionals, you have to compile and link against LibXC!")
2413#endif
2414
2415 ELSE
2416 cpabort("Unknown exchange correction functional!")
2417 END IF
2418
2419 IF (debug_functional) THEN
2420 iounit = cp_logger_get_default_io_unit(logger)
2421 IF (iounit > 0) THEN
2422 WRITE (iounit, "(A)") " ADMM Primary Basis Set Functional"
2423 END IF
2424 xc_fun_section => section_vals_get_subs_vals(admm_env%xc_section_primary, "XC_FUNCTIONAL")
2425 ifun = 0
2426 funct_found = .false.
2427 DO
2428 ifun = ifun + 1
2429 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
2430 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
2431
2432 scale_x = -1000.0_dp
2433 IF (xc_fun%section%name /= "LYP" .AND. xc_fun%section%name /= "VWN") THEN
2434 CALL section_vals_val_get(xc_fun, "SCALE_X", r_val=scale_x)
2435 END IF
2436 IF (xc_fun%section%name == "XWPBE") THEN
2437 CALL section_vals_val_get(xc_fun, "SCALE_X0", r_val=hfx_fraction)
2438 IF (iounit > 0) THEN
2439 WRITE (iounit, "(T5,A,T25,2F10.3)") trim(xc_fun%section%name), scale_x, hfx_fraction
2440 END IF
2441 ELSE
2442 IF (iounit > 0) THEN
2443 WRITE (iounit, "(T5,A,T25,F10.3)") trim(xc_fun%section%name), scale_x
2444 END IF
2445 END IF
2446 END DO
2447
2448 IF (iounit > 0) THEN
2449 WRITE (iounit, "(A)") " Auxiliary Basis Set Functional"
2450 END IF
2451 xc_fun_section => section_vals_get_subs_vals(admm_env%xc_section_aux, "XC_FUNCTIONAL")
2452 ifun = 0
2453 funct_found = .false.
2454 DO
2455 ifun = ifun + 1
2456 xc_fun => section_vals_get_subs_vals2(xc_fun_section, i_section=ifun)
2457 IF (.NOT. ASSOCIATED(xc_fun)) EXIT
2458 scale_x = -1000.0_dp
2459 IF (xc_fun%section%name /= "LYP" .AND. xc_fun%section%name /= "VWN") THEN
2460 CALL section_vals_val_get(xc_fun, "SCALE_X", r_val=scale_x)
2461 END IF
2462 IF (xc_fun%section%name == "XWPBE") THEN
2463 CALL section_vals_val_get(xc_fun, "SCALE_X0", r_val=hfx_fraction)
2464 IF (iounit > 0) THEN
2465 WRITE (iounit, "(T5,A,T25,2F10.3)") trim(xc_fun%section%name), scale_x, hfx_fraction
2466 END IF
2467 ELSE
2468 IF (iounit > 0) THEN
2469 WRITE (iounit, "(T5,A,T25,F10.3)") trim(xc_fun%section%name), scale_x
2470 END IF
2471 END IF
2472 END DO
2473 END IF
2474
2475 END SUBROUTINE create_admm_xc_section
2476
2477! **************************************************************************************************
2478!> \brief Add the hfx contributions to the Hamiltonian
2479!>
2480!> \param matrix_ks Kohn-Sham matrix (updated on exit)
2481!> \param rho_ao electron density expressed in terms of atomic orbitals
2482!> \param qs_env Quickstep environment
2483!> \param update_energy whether to update energy (default: yes)
2484!> \param recalc_integrals whether to recalculate integrals (default: value of HF%TREAT_LSD_IN_CORE)
2485!> \param external_hfx_sections ...
2486!> \param external_x_data ...
2487!> \param external_para_env ...
2488!> \note
2489!> Simplified version of subroutine hfx_ks_matrix()
2490! **************************************************************************************************
2491 SUBROUTINE tddft_hfx_matrix(matrix_ks, rho_ao, qs_env, update_energy, recalc_integrals, &
2492 external_hfx_sections, external_x_data, external_para_env)
2493 TYPE(dbcsr_p_type), DIMENSION(:), INTENT(INOUT), &
2494 TARGET :: matrix_ks, rho_ao
2495 TYPE(qs_environment_type), POINTER :: qs_env
2496 LOGICAL, INTENT(IN), OPTIONAL :: update_energy, recalc_integrals
2497 TYPE(section_vals_type), OPTIONAL, POINTER :: external_hfx_sections
2498 TYPE(hfx_type), DIMENSION(:, :), OPTIONAL, TARGET :: external_x_data
2499 TYPE(mp_para_env_type), OPTIONAL, POINTER :: external_para_env
2500
2501 CHARACTER(LEN=*), PARAMETER :: routinen = 'tddft_hfx_matrix'
2502
2503 INTEGER :: handle, irep, ispin, mspin, n_rep_hf, &
2504 nspins
2505 LOGICAL :: distribute_fock_matrix, &
2506 hfx_treat_lsd_in_core, &
2507 my_update_energy, s_mstruct_changed
2508 REAL(kind=dp) :: eh1, ehfx
2509 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks_kp, rho_ao_kp
2510 TYPE(dft_control_type), POINTER :: dft_control
2511 TYPE(hfx_type), DIMENSION(:, :), POINTER :: x_data
2512 TYPE(mp_para_env_type), POINTER :: para_env
2513 TYPE(qs_energy_type), POINTER :: energy
2514 TYPE(section_vals_type), POINTER :: hfx_sections, input
2515
2516 CALL timeset(routinen, handle)
2517
2518 NULLIFY (dft_control, hfx_sections, input, para_env, matrix_ks_kp, rho_ao_kp)
2519
2520 CALL get_qs_env(qs_env=qs_env, &
2521 dft_control=dft_control, &
2522 energy=energy, &
2523 input=input, &
2524 para_env=para_env, &
2525 s_mstruct_changed=s_mstruct_changed, &
2526 x_data=x_data)
2527
2528 ! This should probably be the HF section from the TDDFPT XC section!
2529 hfx_sections => section_vals_get_subs_vals(input, "DFT%XC%HF")
2530
2531 IF (PRESENT(external_hfx_sections)) hfx_sections => external_hfx_sections
2532 IF (PRESENT(external_x_data)) x_data => external_x_data
2533 IF (PRESENT(external_para_env)) para_env => external_para_env
2534
2535 my_update_energy = .true.
2536 IF (PRESENT(update_energy)) my_update_energy = update_energy
2537
2538 IF (PRESENT(recalc_integrals)) s_mstruct_changed = recalc_integrals
2539
2540 cpassert(dft_control%nimages == 1)
2541 nspins = dft_control%nspins
2542
2543 CALL section_vals_get(hfx_sections, n_repetition=n_rep_hf)
2544 CALL section_vals_val_get(hfx_sections, "TREAT_LSD_IN_CORE", l_val=hfx_treat_lsd_in_core, &
2545 i_rep_section=1)
2546
2547 CALL section_vals_get(hfx_sections, n_repetition=n_rep_hf)
2548 distribute_fock_matrix = .true.
2549
2550 mspin = 1
2551 IF (hfx_treat_lsd_in_core) mspin = nspins
2552
2553 matrix_ks_kp(1:nspins, 1:1) => matrix_ks(1:nspins)
2554 rho_ao_kp(1:nspins, 1:1) => rho_ao(1:nspins)
2555
2556 DO irep = 1, n_rep_hf
2557 ! the real hfx calulation
2558 ehfx = 0.0_dp
2559
2560 IF (x_data(irep, 1)%do_hfx_ri) THEN
2561 CALL hfx_ri_update_ks(qs_env, x_data(irep, 1)%ri_data, matrix_ks_kp, ehfx, &
2562 rho_ao=rho_ao_kp, geometry_did_change=s_mstruct_changed, &
2563 nspins=nspins, hf_fraction=x_data(irep, 1)%general_parameter%fraction)
2564
2565 ELSE
2566 DO ispin = 1, mspin
2567 CALL integrate_four_center(qs_env, x_data, matrix_ks_kp, eh1, rho_ao_kp, hfx_sections, para_env, &
2568 s_mstruct_changed, irep, distribute_fock_matrix, ispin=ispin)
2569 ehfx = ehfx + eh1
2570 END DO
2571 END IF
2572 END DO
2573 IF (my_update_energy) energy%ex = ehfx
2574
2575 CALL timestop(handle)
2576 END SUBROUTINE tddft_hfx_matrix
2577
2578END MODULE hfx_admm_utils
Types and set/get functions for auxiliary density matrix methods.
subroutine, public admm_dm_create(admm_dm, admm_control, nspins, natoms)
Create a new admm_dm type.
Contains ADMM methods which require molecular orbitals.
subroutine, public scale_dm(qs_env, rho_ao_orb, scale_back)
Scale density matrix by gsi(ispin), is needed for force scaling in ADMMP.
subroutine, public kpoint_calc_admm_matrices(qs_env, calculate_forces)
Fill the ADMM overlp and basis change matrices in the KP env based on the real-space array.
Types and set/get functions for auxiliary density matrix methods.
Definition admm_types.F:15
subroutine, public get_admm_env(admm_env, mo_derivs_aux_fit, mos_aux_fit, sab_aux_fit, sab_aux_fit_asymm, sab_aux_fit_vs_orb, matrix_s_aux_fit, matrix_s_aux_fit_kp, matrix_s_aux_fit_vs_orb, matrix_s_aux_fit_vs_orb_kp, task_list_aux_fit, matrix_ks_aux_fit, matrix_ks_aux_fit_kp, matrix_ks_aux_fit_im, matrix_ks_aux_fit_dft, matrix_ks_aux_fit_hfx, matrix_ks_aux_fit_dft_kp, matrix_ks_aux_fit_hfx_kp, rho_aux_fit, rho_aux_fit_buffer, admm_dm)
Get routine for the ADMM env.
Definition admm_types.F:599
subroutine, public set_admm_env(admm_env, mo_derivs_aux_fit, mos_aux_fit, sab_aux_fit, sab_aux_fit_asymm, sab_aux_fit_vs_orb, matrix_s_aux_fit, matrix_s_aux_fit_kp, matrix_s_aux_fit_vs_orb, matrix_s_aux_fit_vs_orb_kp, task_list_aux_fit, matrix_ks_aux_fit, matrix_ks_aux_fit_kp, matrix_ks_aux_fit_im, matrix_ks_aux_fit_dft, matrix_ks_aux_fit_hfx, matrix_ks_aux_fit_dft_kp, matrix_ks_aux_fit_hfx_kp, rho_aux_fit, rho_aux_fit_buffer, admm_dm)
Set routine for the ADMM env.
Definition admm_types.F:683
subroutine, public admm_env_create(admm_env, admm_control, mos, para_env, natoms, nao_aux_fit, blacs_env_ext)
creates ADMM environment, initializes the basic types
Definition admm_types.F:220
Define the atomic kind types and their sub types.
subroutine, public add_basis_set_to_container(container, basis_set, basis_set_type)
...
subroutine, public get_gto_basis_set(gto_basis_set, name, aliases, norm_type, kind_radius, ncgf, nset, nsgf, cgf_symbol, sgf_symbol, norm_cgf, set_radius, lmax, lmin, lx, ly, lz, m, ncgf_set, npgf, nsgf_set, nshell, cphi, pgf_radius, sphi, scon, zet, first_cgf, first_sgf, l, last_cgf, last_sgf, n, gcc, maxco, maxl, maxpgf, maxsgf_set, maxshell, maxso, nco_sum, npgf_sum, nshell_sum, maxder, short_kind_radius, npgf_seg_sum, ccon)
...
subroutine, public copy_gto_basis_set(basis_set_in, basis_set_out)
...
Handles all functions related to the CELL.
Definition cell_types.F:15
real(kind=dp) function, public plane_distance(h, k, l, cell)
Calculate the distance between two lattice planes as defined by a triple of Miller indices (hkl).
Definition cell_types.F:324
methods related to the blacs parallel environment
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_init_p(matrix)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
DBCSR operations in CP2K.
subroutine, public cp_dbcsr_m_by_n_from_row_template(matrix, template, n, sym)
Utility function to create dbcsr matrix, m x n matrix (n arbitrary) with the same processor grid and ...
pool for for elements that are retained and released
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
creates a new full matrix with the given structure
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
stores a lists of integer that are local to a processor. The idea is that these integers represent ob...
stores a mapping of 2D info (e.g. matrix) on a 2D processor distribution (i.e. blacs grid) where cpus...
Definition of the atomic potential types.
Utilities for hfx and admm methods.
subroutine, public hfx_admm_init(qs_env, calculate_forces, ext_xc_section)
...
subroutine, public tddft_hfx_matrix(matrix_ks, rho_ao, qs_env, update_energy, recalc_integrals, external_hfx_sections, external_x_data, external_para_env)
Add the hfx contributions to the Hamiltonian.
subroutine, public aux_admm_init(qs_env, mos, admm_env, admm_control, basis_type)
Minimal setup routine for admm_env No forces No k-points No DFT correction terms.
subroutine, public hfx_ks_matrix(qs_env, matrix_ks, rho, energy, calculate_forces, just_energy, v_rspace_new, v_tau_rspace, ext_xc_section)
Add the hfx contributions to the Hamiltonian.
subroutine, public create_admm_xc_section(x_data, xc_section, admm_env)
This routine modifies the xc section depending on the potential type used for the HF exchange and the...
subroutine, public hfx_ks_matrix_kp(qs_env, matrix_ks, energy, calculate_forces)
Add the HFX K-point contribution to the real-space Hamiltonians.
Routines to calculate derivatives with respect to basis function origin.
subroutine, public derivatives_four_center(qs_env, rho_ao, rho_ao_resp, hfx_section, para_env, irep, use_virial, adiabatic_rescale_factor, resp_only, external_x_data, nspins)
computes four center derivatives for a full basis set and updates the forcesfock_4c arrays....
Routines to calculate HFX energy and potential.
subroutine, public integrate_four_center(qs_env, x_data, ks_matrix, ehfx, rho_ao, hfx_section, para_env, geometry_did_change, irep, distribute_fock_matrix, ispin, nspins)
computes four center integrals for a full basis set and updates the Kohn-Sham-Matrix and energy....
Test routines for HFX caclulations using PW.
subroutine, public pw_hfx(qs_env, ehfx, hfx_section, poisson_env, auxbas_pw_pool, irep)
computes the Hartree-Fock energy brute force in a pw basis
RI-methods for HFX and K-points. \auhtor Augustin Bussy (01.2023).
Definition hfx_ri_kp.F:13
subroutine, public hfx_ri_update_forces_kp(qs_env, ri_data, nspins, hf_fraction, rho_ao, use_virial)
Update the K-points RI-HFX forces.
Definition hfx_ri_kp.F:862
subroutine, public hfx_ri_update_ks_kp(qs_env, ri_data, ks_matrix, ehfx, rho_ao, geometry_did_change, nspins, hf_fraction)
Update the KS matrices for each real-space image.
Definition hfx_ri_kp.F:456
RI-methods for HFX.
Definition hfx_ri.F:12
subroutine, public hfx_ri_update_ks(qs_env, ri_data, ks_matrix, ehfx, mos, rho_ao, geometry_did_change, nspins, hf_fraction)
...
Definition hfx_ri.F:1041
subroutine, public hfx_ri_update_forces(qs_env, ri_data, nspins, hf_fraction, rho_ao, rho_ao_resp, mos, use_virial, resp_only, rescale_factor)
the general routine that calls the relevant force code
Definition hfx_ri.F:3044
Types and set/get functions for HFX.
Definition hfx_types.F:16
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public do_admm_aux_exch_func_opt_libxc
integer, parameter, public do_admm_purify_none
integer, parameter, public xc_funct_no_shortcut
integer, parameter, public do_admm_aux_exch_func_sx_libxc
integer, parameter, public do_admm_aux_exch_func_bee
integer, parameter, public do_potential_mix_cl
integer, parameter, public do_admm_basis_projection
integer, parameter, public do_admm_aux_exch_func_default_libxc
integer, parameter, public do_admm_aux_exch_func_opt
integer, parameter, public do_admm_aux_exch_func_none
integer, parameter, public do_admm_aux_exch_func_bee_libxc
integer, parameter, public do_admm_aux_exch_func_pbex_libxc
integer, parameter, public do_admm_aux_exch_func_default
integer, parameter, public do_potential_truncated
integer, parameter, public do_admm_charge_constrained_projection
integer, parameter, public do_potential_id
integer, parameter, public do_potential_coulomb
integer, parameter, public do_potential_short
integer, parameter, public do_potential_mix_cl_trunc
integer, parameter, public xc_none
integer, parameter, public do_potential_long
integer, parameter, public do_admm_aux_exch_func_pbex
objects that represent the structure of input sections and the data contained in an input section
subroutine, public section_vals_val_set(section_vals, keyword_name, i_rep_section, i_rep_val, val, l_val, i_val, r_val, c_val, l_vals_ptr, i_vals_ptr, r_vals_ptr, c_vals_ptr)
sets the requested value
type(section_vals_type) function, pointer, public section_vals_get_subs_vals2(section_vals, i_section, i_rep_section)
returns the values of the n-th non default subsection (null if no such section exists (not so many no...
subroutine, public section_vals_remove_values(section_vals)
removes the values of a repetition of the section
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_get(section_vals, ref_count, n_repetition, n_subs_vals_rep, section, explicit)
returns various attributes about the section_vals
subroutine, public section_vals_duplicate(section_vals_in, section_vals_out, i_rep_start, i_rep_end)
creates a deep copy from section_vals_in to section_vals_out
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Routines needed for kpoint calculation.
subroutine, public kpoint_initialize_mos(kpoint, mos, added_mos, for_aux_fit)
Initialize a set of MOs and density matrix for each kpoint (kpoint group).
Datatype to translate between k-points (2d) and gamma-point (1d) code.
subroutine, public kpoint_transitional_release(this)
Release the matrix set, using the right pointer.
subroutine, public set_2d_pointer(this, ptr_2d)
Assigns a 2D pointer.
Types and basic routines needed for a kpoint calculation.
subroutine, public get_kpoint_info(kpoint, kp_scheme, nkp_grid, kp_shift, symmetry, verbose, full_grid, use_real_wfn, eps_geo, parallel_group_size, kp_range, nkp, xkp, wkp, para_env, blacs_env_all, para_env_kp, para_env_inter_kp, blacs_env, kp_env, kp_aux_env, mpools, iogrp, nkp_groups, kp_dist, cell_to_index, index_to_cell, sab_nl, sab_nl_nosym, inversion_symmetry_only, symmetry_backend, symmetry_reduction_method, gamma_centered, lattice_fft)
Retrieve information from a kpoint environment.
2- and 3-center electron repulsion integral routines based on libint2 Currently available operators: ...
real(kind=dp), parameter, public cutoff_screen_factor
Collection of simple mathematical functions and subroutines.
Definition mathlib.F:15
subroutine, public erfc_cutoff(eps, omg, r_cutoff)
compute a truncation radius for the shortrange operator
Definition mathlib.F:1827
Interface to the message passing library MPI.
Define the data structure for the molecule information.
Define the data structure for the particle information.
subroutine, public get_paw_proj_set(paw_proj_set, csprj, chprj, first_prj, first_prjs, last_prj, local_oce_sphi_h, local_oce_sphi_s, maxl, ncgauprj, nsgauprj, nsatbas, nsotot, nprj, o2nindex, n2oindex, rcprj, rzetprj, zisomin, zetprj)
Get informations about a paw projectors set.
container for various plainwaves related things
subroutine, public pw_env_get(pw_env, pw_pools, cube_info, gridlevel_info, auxbas_pw_pool, auxbas_grid, auxbas_rs_desc, auxbas_rs_grid, rs_descs, rs_grids, xc_pw_pool, vdw_pw_pool, poisson_env, interp_section)
returns the various attributes of the pw env
functions related to the poisson solver on regular grids
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, matrix_vhxc, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
subroutine, public set_qs_env(qs_env, super_cell, mos, qmmm, qmmm_periodic, mimic, ewald_env, ewald_pw, mpools, rho_external, external_vxc, mask, scf_control, rel_control, qs_charges, ks_env, ks_qmmm_env, wf_history, scf_env, active_space, input, oce, rho_atom_set, rho0_atom_set, rho0_mpole, run_rtp, rtp, rhoz_set, rhoz_tot, ecoul_1c, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, efield, rhoz_cneo_set, linres_control, xas_env, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, ls_scf_env, do_transport, transport_env, lri_env, lri_density, exstate_env, ec_env, dispersion_env, harris_env, gcp_env, mp2_env, bs_env, kg_env, force, kpoints, wanniercentres, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Set the QUICKSTEP environment.
Calculate the interaction radii for the operator matrix calculation.
subroutine, public init_interaction_radii(qs_control, qs_kind_set)
Initialize all the atomic kind radii for a given threshold value.
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, cneo_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, hund_j, u_of_dft_plus_u, j_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, j0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, proj_shell_charge, lr_atom, do_mtlr, u_j_loop, ao_coef, init_u_ramping_each_scf, reltmat, ghost, monovalent, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
subroutine, public init_gapw_nlcc(qs_kind_set)
...
subroutine, public init_gapw_basis_set(qs_kind_set, qs_control, force_env_section, modify_qs_control)
...
subroutine, public get_qs_kind_set(qs_kind_set, all_potential_present, tnadd_potential_present, gth_potential_present, sgp_potential_present, paw_atom_present, dft_plus_u_atom_present, maxcgf, maxsgf, maxco, maxco_proj, maxgtops, maxlgto, maxlprj, maxnset, maxsgf_set, ncgf, npgf, nset, nsgf, nshell, maxpol, maxlppl, maxlppnl, maxppnl, nelectron, maxder, max_ngrid_rad, max_sph_harm, maxg_iso_not0, lmax_rho0, basis_rcut, do_mtlr_present, basis_type, total_zeff_corr, npgf_seg, cneo_potential_present, nkind_q, natom_q)
Get attributes of an atomic kind set.
subroutine, public local_rho_set_create(local_rho_set)
...
wrapper for the pools of matrixes
subroutine, public mpools_get(mpools, ao_mo_fm_pools, ao_ao_fm_pools, mo_mo_fm_pools, ao_mosub_fm_pools, mosub_mosub_fm_pools, maxao_maxmo_fm_pool, maxao_maxao_fm_pool, maxmo_maxmo_fm_pool)
returns various attributes of the mpools (notably the pools contained in it)
Definition and initialisation of the mo data type.
Definition qs_mo_types.F:22
subroutine, public init_mo_set(mo_set, fm_pool, fm_ref, fm_struct, name, counter)
initializes an allocated mo_set. eigenvalues, mo_coeff, occupation_numbers are valid only after this ...
subroutine, public allocate_mo_set(mo_set, nao, nmo, nelectron, n_el_f, maxocc, flexible_electron_count)
Allocates a mo set and partially initializes it (nao,nmo,nelectron, and flexible_electron_count are v...
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kts, mu, flexible_electron_count)
Get the components of a MO set data structure.
Define the neighbor list data types and the corresponding functionality.
subroutine, public release_neighbor_list_sets(nlists)
releases an array of neighbor_list_sets
Generate the atomic neighbor lists.
subroutine, public atom2d_cleanup(atom2d)
free the internals of atom2d
subroutine, public pair_radius_setup(present_a, present_b, radius_a, radius_b, pair_radius, prmin)
...
subroutine, public build_neighbor_lists(ab_list, particle_set, atom, cell, pair_radius, subcells, mic, symmetric, molecular, subset_of_mol, current_subset, operator_type, nlname, atomb_to_keep, stable_images)
Build simple pair neighbor lists.
subroutine, public write_neighbor_lists(ab, particle_set, cell, para_env, neighbor_list_section, nl_type, middle_name, nlname)
Write a set of neighbor lists to the output unit.
subroutine, public atom2d_build(atom2d, distribution_1d, distribution_2d, atomic_kind_set, molecule_set, molecule_only, particle_set)
Build some distribution structure of atoms, refactored from build_qs_neighbor_lists.
Routines for the construction of the coefficients for the expansion of the atomic densities rho1_hard...
subroutine, public build_oce_matrices(intac, calculate_forces, nder, qs_kind_set, particle_set, sap_oce, eps_fit)
Set up the sparse matrix for the coefficients of one center expansions This routine uses the same log...
subroutine, public allocate_oce_set(oce_set, nkind)
Allocate and initialize the matrix set of oce coefficients.
subroutine, public create_oce_set(oce_set)
...
Calculation of overlap matrix, its derivatives and forces.
Definition qs_overlap.F:19
subroutine, public build_overlap_matrix(ks_env, matrix_s, matrixkp_s, matrix_name, nderivative, basis_type_a, basis_type_b, sab_nl, calculate_forces, matrix_p, matrixkp_p, ext_kpoints)
Calculation of the overlap matrix over Cartesian Gaussian functions.
Definition qs_overlap.F:121
subroutine, public init_rho_atom(rho_atom_set, atomic_kind_set, qs_kind_set, dft_control, para_env)
...
methods of the rho structure (defined in qs_rho_types)
subroutine, public qs_rho_rebuild(rho, qs_env, rebuild_ao, rebuild_grids, admm, pw_env_external)
rebuilds rho (if necessary allocating and initializing it)
superstucture that hold various representations of the density and keeps track of which ones are vali...
subroutine, public qs_rho_get(rho_struct, rho_ao, rho_ao_im, rho_ao_kp, rho_ao_im_kp, rho_r, drho_r, rho_g, drho_g, tau_r, tau_g, rho_r_valid, drho_r_valid, rho_g_valid, drho_g_valid, tau_r_valid, tau_g_valid, tot_rho_r, tot_rho_g, rho_r_sccs, soft_valid, complex_rho_ao)
returns info about the density described by this object. If some representation is not available an e...
subroutine, public qs_rho_create(rho)
Allocates a new instance of rho.
Types and set_get for real time propagation depending on runtype and diagonalization method different...
generate the tasks lists used by collocate and integrate routines
subroutine, public generate_qs_task_list(ks_env, task_list, basis_type, reorder_rs_grid_ranks, skip_load_balance_distributed, pw_env_external, sab_orb_external, ext_kpoints)
...
types for task lists
subroutine, public deallocate_task_list(task_list)
deallocates the components and the object itself
subroutine, public allocate_task_list(task_list)
allocates and initialised the components of the task_list_type
subroutine, public rescale_xc_potential(qs_env, ks_matrix, rho, energy, v_rspace_new, v_tau_rspace, hf_energy, just_energy, calculate_forces, use_virial)
A subtype of the admm_env that contains the extra data needed for an ADMM GAPW calculation.
Definition admm_types.F:85
stores some data used in wavefunction fitting
Definition admm_types.F:120
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
Definition cell_types.F:60
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
keeps the information about the structure of a full matrix
represent a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...
structure to store local (to a processor) ordered lists of integers.
distributes pairs on a 2d grid of processors
stores some data used in construction of Kohn-Sham matrix
Definition hfx_types.F:514
Contains information about kpoints.
stores all the informations relevant to an mpi environment
contained for different pw related things
environment for the poisson solver
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
Provides all information about a quickstep kind.
calculation environment to calculate the ks matrix, holds all the needed vars. assumes that the core ...
keeps the density in various representations, keeping track of which ones are valid.