(git:339af6c)
Loading...
Searching...
No Matches
qs_active_space_methods.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2025 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Determine active space Hamiltonian
10!> \par History
11!> 04.2016 created [JGH]
12!> \author JGH
13! **************************************************************************************************
15 USE admm_types, ONLY: admm_type, &
25 srules, &
36 USE cp_files, ONLY: close_file, &
43 USE cp_fm_types, ONLY: &
49 USE cp_output_handling, ONLY: &
54 USE cp_dbcsr_api, ONLY: &
55 dbcsr_copy, dbcsr_csr_create, dbcsr_csr_type, dbcsr_p_type, dbcsr_type, dbcsr_release, &
59 USE erf_complex, ONLY: erfz_fast
61 USE input_constants, ONLY: &
71 USE iso_c_binding, ONLY: c_null_char
72 USE kinds, ONLY: default_path_length, &
74 dp, &
75 int_8
77 USE machine, ONLY: m_walltime, m_flush
78 USE mathlib, ONLY: diamat_all
79 USE mathconstants, ONLY: fourpi, twopi, pi, rootpi
81 USE message_passing, ONLY: mp_comm_type, &
85 USE mt_util, ONLY: mt0d
89 USE periodic_table, ONLY: ptable
90 USE physcon, ONLY: angstrom, bohr
92 USE pw_env_methods, ONLY: pw_env_create, &
94 USE pw_env_types, ONLY: pw_env_get, &
100 pw_transfer, &
105 USE pw_poisson_types, ONLY: analytic0d, &
106 periodic3d, &
111 USE pw_pool_types, ONLY: &
113 USE pw_types, ONLY: &
116 USE qcschema, ONLY: qcschema_env_create, &
124 eri_type, &
132 USE qs_environment_types, ONLY: get_qs_env, &
135 USE qs_integrate_potential, ONLY: integrate_v_rspace
136 USE qs_kind_types, ONLY: qs_kind_type
139 USE qs_ks_types, ONLY: qs_ks_did_change, &
143 USE qs_mo_types, ONLY: allocate_mo_set, &
144 get_mo_set, &
145 init_mo_set, &
150 USE qs_rho_types, ONLY: qs_rho_get, &
152 USE qs_subsys_types, ONLY: qs_subsys_get, &
156#ifndef __NO_SOCKETS
157 USE sockets_interface, ONLY: accept_socket, &
158 close_socket, &
161 readbuffer, &
164#endif
169 USE util, ONLY: get_limit
170#include "./base/base_uses.f90"
171
172 IMPLICIT NONE
173 PRIVATE
174
175 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_active_space_methods'
176
177 PUBLIC :: active_space_main
178
179 TYPE, EXTENDS(eri_type_eri_element_func) :: eri_fcidump_print
180 INTEGER :: unit_nr = -1, bra_start = -1, ket_start = -1
181 CONTAINS
182 PROCEDURE :: func => eri_fcidump_print_func
183 END TYPE eri_fcidump_print
184
185 TYPE, EXTENDS(eri_type_eri_element_func) :: eri_fcidump_checksum
186 INTEGER :: bra_start = 0, ket_start = 0
187 REAL(KIND=dp) :: checksum = 0.0_dp
188 CONTAINS
189 PROCEDURE, PASS :: set => eri_fcidump_set
190 PROCEDURE :: func => eri_fcidump_checksum_func
191 END TYPE eri_fcidump_checksum
192
193CONTAINS
194
195! **************************************************************************************************
196!> \brief Sets the starting indices of the bra and ket.
197!> \param this object reference
198!> \param bra_start starting index of the bra
199!> \param ket_start starting index of the ket
200! **************************************************************************************************
201 SUBROUTINE eri_fcidump_set(this, bra_start, ket_start)
202 CLASS(eri_fcidump_checksum) :: this
203 INTEGER, INTENT(IN) :: bra_start, ket_start
204 this%bra_start = bra_start
205 this%ket_start = ket_start
206 END SUBROUTINE eri_fcidump_set
207
208! **************************************************************************************************
209!> \brief Main method for determining the active space Hamiltonian
210!> \param qs_env ...
211! **************************************************************************************************
212 SUBROUTINE active_space_main(qs_env)
213 TYPE(qs_environment_type), POINTER :: qs_env
214
215 CHARACTER(len=*), PARAMETER :: routinen = 'active_space_main'
216
217 CHARACTER(len=10) :: cshell, lnam(5)
218 CHARACTER(len=default_path_length) :: qcschema_filename
219 CHARACTER(LEN=default_string_length) :: basis_type
220 INTEGER :: as_solver, eri_method, eri_operator, eri_print, group_size, handle, i, iatom, &
221 ishell, isp, ispin, iw, j, jm, m, max_orb_ind, mselect, n1, n2, nao, natom, nel, &
222 nelec_active, nelec_inactive, nelec_total, nmo, nmo_active, nmo_available, nmo_inactive, &
223 nmo_inactive_remaining, nmo_occ, nmo_virtual, nn1, nn2, nrow_global, nspins
224 INTEGER, DIMENSION(5) :: nshell
225 INTEGER, DIMENSION(:), POINTER :: invals
226 LOGICAL :: do_ddapc, do_kpoints, ex_omega, &
227 ex_operator, ex_perd, ex_rcut, &
228 explicit, stop_after_print, store_wfn
229 REAL(kind=dp) :: alpha, eri_eps_filter, eri_eps_grid, eri_eps_int, eri_gpw_cutoff, &
230 eri_op_omega, eri_rcut, eri_rel_cutoff, fel, focc, maxocc, nze_percentage
231 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: eigenvalues
232 REAL(kind=dp), DIMENSION(:), POINTER :: evals_virtual
233 TYPE(active_space_type), POINTER :: active_space_env
234 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
235 TYPE(cell_type), POINTER :: cell
236 TYPE(cp_blacs_env_type), POINTER :: context
237 TYPE(cp_fm_struct_type), POINTER :: fm_struct_tmp
238 TYPE(cp_fm_type) :: fm_dummy, mo_virtual
239 TYPE(cp_fm_type), POINTER :: fm_target_active, fm_target_inactive, &
240 fmat, mo_coeff, mo_ref, mo_target
241 TYPE(cp_logger_type), POINTER :: logger
242 TYPE(dbcsr_csr_type), POINTER :: eri_mat
243 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: ks_matrix, rho_ao, s_matrix
244 TYPE(dbcsr_type), POINTER :: denmat
245 TYPE(dft_control_type), POINTER :: dft_control
246 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
247 TYPE(mo_set_type), POINTER :: mo_set, mo_set_active, mo_set_inactive
248 TYPE(mp_para_env_type), POINTER :: para_env
249 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
250 TYPE(preconditioner_type), POINTER :: local_preconditioner
251 TYPE(qcschema_type) :: qcschema_env
252 TYPE(qs_energy_type), POINTER :: energy
253 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
254 TYPE(qs_ks_env_type), POINTER :: ks_env
255 TYPE(qs_rho_type), POINTER :: rho
256 TYPE(scf_control_type), POINTER :: scf_control
257 TYPE(section_vals_type), POINTER :: adiabatic_rescaling, as_input, &
258 hfx_section, input, loc_print, &
259 loc_section, print_orb, xc_section
260
261 !--------------------------------------------------------------------------------------------!
262
263 CALL get_qs_env(qs_env, input=input)
264 as_input => section_vals_get_subs_vals(input, "DFT%ACTIVE_SPACE")
265 CALL section_vals_get(as_input, explicit=explicit)
266 IF (.NOT. explicit) RETURN
267 CALL timeset(routinen, handle)
268
269 logger => cp_get_default_logger()
271
272 IF (iw > 0) THEN
273 WRITE (iw, '(/,T2,A)') &
274 '!-----------------------------------------------------------------------------!'
275 WRITE (iw, '(T26,A)') "Active Space Embedding Module"
276 WRITE (iw, '(T2,A)') &
277 '!-----------------------------------------------------------------------------!'
278 END IF
279
280 ! k-points?
281 CALL get_qs_env(qs_env, do_kpoints=do_kpoints, dft_control=dft_control)
282 IF (do_kpoints) THEN
283 CALL cp_abort(__location__, "k-points not supported in active space module")
284 END IF
285
286 ! adiabatic rescaling?
287 adiabatic_rescaling => section_vals_get_subs_vals(input, "DFT%XC%ADIABATIC_RESCALING")
288 CALL section_vals_get(adiabatic_rescaling, explicit=explicit)
289 IF (explicit) THEN
290 CALL cp_abort(__location__, "Adiabatic rescaling not supported in active space module")
291 END IF
292
293 ! Setup the possible usage of DDAPC charges
294 do_ddapc = dft_control%qs_control%ddapc_restraint .OR. &
295 qs_env%cp_ddapc_ewald%do_decoupling .OR. &
296 qs_env%cp_ddapc_ewald%do_qmmm_periodic_decpl .OR. &
297 qs_env%cp_ddapc_ewald%do_solvation
298 IF (do_ddapc) THEN
299 CALL cp_abort(__location__, "DDAPC charges are not supported in the active space module")
300 END IF
301 IF (dft_control%do_sccs) THEN
302 CALL cp_abort(__location__, "SCCS is not supported in the active space module")
303 END IF
304 IF (dft_control%correct_surf_dip) THEN
305 IF (dft_control%surf_dip_correct_switch) THEN
306 CALL cp_abort(__location__, "Surface dipole correction not supported in the AS module")
307 END IF
308 END IF
309 IF (dft_control%smeagol_control%smeagol_enabled) THEN
310 CALL cp_abort(__location__, "SMEAGOL is not supported in the active space module")
311 END IF
312 IF (dft_control%qs_control%do_kg) THEN
313 CALL cp_abort(__location__, "KG correction not supported in the active space module")
314 END IF
315
316 NULLIFY (active_space_env)
317 CALL create_active_space_type(active_space_env)
318 active_space_env%energy_total = 0.0_dp
319 active_space_env%energy_ref = 0.0_dp
320 active_space_env%energy_inactive = 0.0_dp
321 active_space_env%energy_active = 0.0_dp
322
323 ! input options
324
325 ! figure out what needs to be printed/stored
326 IF (btest(cp_print_key_should_output(logger%iter_info, as_input, "FCIDUMP"), cp_p_file)) THEN
327 active_space_env%fcidump = .true.
328 END IF
329
330 CALL section_vals_val_get(as_input, "QCSCHEMA", c_val=qcschema_filename, explicit=explicit)
331 IF (explicit) THEN
332 active_space_env%qcschema = .true.
333 active_space_env%qcschema_filename = qcschema_filename
334 END IF
335
336 CALL section_vals_val_get(as_input, "ACTIVE_ELECTRONS", i_val=nelec_active)
337 CALL get_qs_env(qs_env, nelectron_total=nelec_total)
338
339 IF (nelec_active <= 0) cpabort("Specify a positive number of active electrons.")
340 IF (nelec_active > nelec_total) cpabort("More active electrons than total electrons.")
341
342 nelec_inactive = nelec_total - nelec_active
343 IF (mod(nelec_inactive, 2) /= 0) THEN
344 cpabort("The remaining number of inactive electrons has to be even.")
345 END IF
346
347 CALL section_vals_val_get(as_input, "ALPHA", r_val=alpha)
348 IF (alpha < 0.0 .OR. alpha > 1.0) cpabort("Specify a damping factor between 0 and 1.")
349 active_space_env%alpha = alpha
350
351 IF (iw > 0) THEN
352 WRITE (iw, '(T3,A,T70,I10)') "Total number of electrons", nelec_total
353 WRITE (iw, '(T3,A,T70,I10)') "Number of inactive electrons", nelec_inactive
354 WRITE (iw, '(T3,A,T70,I10)') "Number of active electrons", nelec_active
355 END IF
356
357 CALL get_qs_env(qs_env, dft_control=dft_control)
358 nspins = dft_control%nspins
359
360 active_space_env%nelec_active = nelec_active
361 active_space_env%nelec_inactive = nelec_inactive
362 active_space_env%nelec_total = nelec_total
363 active_space_env%nspins = nspins
364 active_space_env%multiplicity = dft_control%multiplicity
365
366 ! define the active/inactive space orbitals
367 CALL section_vals_val_get(as_input, "ACTIVE_ORBITALS", explicit=explicit, i_val=nmo_active)
368 IF (.NOT. explicit) THEN
369 CALL cp_abort(__location__, "Number of Active Orbitals has to be specified.")
370 END IF
371 active_space_env%nmo_active = nmo_active
372 ! this is safe because nelec_inactive is always even
373 nmo_inactive = nelec_inactive/2
374 active_space_env%nmo_inactive = nmo_inactive
375
376 CALL section_vals_val_get(as_input, "ORBITAL_SELECTION", i_val=mselect)
377 IF (iw > 0) THEN
378 SELECT CASE (mselect)
379 CASE DEFAULT
380 cpabort("Unknown orbital selection method")
381 CASE (casci_canonical)
382 WRITE (iw, '(/,T3,A)') &
383 "Active space orbitals selected using energy ordered canonical orbitals"
384 CASE (wannier_projection)
385 WRITE (iw, '(/,T3,A)') &
386 "Active space orbitals selected using projected Wannier orbitals"
387 CASE (mao_projection)
388 WRITE (iw, '(/,T3,A)') &
389 "Active space orbitals selected using modified atomic orbitals (MAO)"
390 CASE (manual_selection)
391 WRITE (iw, '(/,T3,A)') &
392 "Active space orbitals selected manually"
393 END SELECT
394
395 WRITE (iw, '(T3,A,T70,I10)') "Number of inactive orbitals", nmo_inactive
396 WRITE (iw, '(T3,A,T70,I10)') "Number of active orbitals", nmo_active
397 END IF
398
399 ! get projection spaces
400 CALL section_vals_val_get(as_input, "SUBSPACE_ATOM", i_val=iatom, explicit=explicit)
401 IF (explicit) THEN
402 CALL get_qs_env(qs_env, natom=natom)
403 IF (iatom <= 0 .OR. iatom > natom) THEN
404 IF (iw > 0) THEN
405 WRITE (iw, '(/,T3,A,I3)') "ERROR: SUBSPACE_ATOM number is not valid", iatom
406 END IF
407 cpabort("Select a valid SUBSPACE_ATOM")
408 END IF
409 END IF
410 CALL section_vals_val_get(as_input, "SUBSPACE_SHELL", c_val=cshell, explicit=explicit)
411 nshell = 0
412 lnam = ""
413 IF (explicit) THEN
414 cshell = adjustl(cshell)
415 n1 = 1
416 DO i = 1, 5
417 ishell = i
418 IF (cshell(n1:n1) == " ") THEN
419 ishell = ishell - 1
420 EXIT
421 END IF
422 READ (cshell(n1:), "(I1,A1)") nshell(i), lnam(i)
423 n1 = n1 + 2
424 END DO
425 END IF
426
427 ! generate orbitals
428 SELECT CASE (mselect)
429 CASE DEFAULT
430 cpabort("Unknown orbital selection method")
431 CASE (casci_canonical)
432 CALL get_qs_env(qs_env, mos=mos)
433
434 ! total number of occupied orbitals, i.e. inactive plus active MOs
435 nmo_occ = nmo_inactive + nmo_active
436
437 ! set inactive orbital indices, these are trivially 1...nmo_inactive
438 ALLOCATE (active_space_env%inactive_orbitals(nmo_inactive, nspins))
439 DO ispin = 1, nspins
440 DO i = 1, nmo_inactive
441 active_space_env%inactive_orbitals(i, ispin) = i
442 END DO
443 END DO
444
445 ! set active orbital indices, these are shifted by nmo_inactive
446 ALLOCATE (active_space_env%active_orbitals(nmo_active, nspins))
447 DO ispin = 1, nspins
448 DO i = 1, nmo_active
449 active_space_env%active_orbitals(i, ispin) = nmo_inactive + i
450 END DO
451 END DO
452
453 ! allocate and initialize inactive and active mo coefficients.
454 ! These are stored in a data structure for the full occupied space:
455 ! for inactive mos, the active subset is set to zero, vice versa for the active mos
456 ! TODO: allocate data structures only for the eaxct number MOs
457 maxocc = 2.0_dp
458 IF (nspins > 1) maxocc = 1.0_dp
459 ALLOCATE (active_space_env%mos_active(nspins))
460 ALLOCATE (active_space_env%mos_inactive(nspins))
461 DO ispin = 1, nspins
462 CALL get_mo_set(mos(ispin), mo_coeff=mo_ref, nao=nao)
463 CALL cp_fm_get_info(mo_ref, context=context, para_env=para_env, nrow_global=nrow_global)
464 ! the right number of active electrons per spin channel is initialized further down
465 CALL allocate_mo_set(active_space_env%mos_active(ispin), nao, nmo_occ, 0, 0.0_dp, maxocc, 0.0_dp)
466 CALL cp_fm_struct_create(fm_struct_tmp, para_env=para_env, context=context, &
467 nrow_global=nrow_global, ncol_global=nmo_occ)
468 CALL init_mo_set(active_space_env%mos_active(ispin), fm_struct=fm_struct_tmp, name="Active Space MO")
469 CALL cp_fm_struct_release(fm_struct_tmp)
470 IF (nspins == 2) THEN
471 nel = nelec_inactive/2
472 ELSE
473 nel = nelec_inactive
474 END IF
475 CALL allocate_mo_set(active_space_env%mos_inactive(ispin), nao, nmo_occ, nel, &
476 REAL(nel, kind=dp), maxocc, 0.0_dp)
477 CALL cp_fm_struct_create(fm_struct_tmp, para_env=para_env, context=context, &
478 nrow_global=nrow_global, ncol_global=nmo_occ)
479 CALL init_mo_set(active_space_env%mos_inactive(ispin), fm_struct=fm_struct_tmp, name="Inactive Space MO")
480 CALL cp_fm_struct_release(fm_struct_tmp)
481 END DO
482
483 ! create canonical orbitals
484 IF (dft_control%restricted) THEN
485 cpabort("Unclear how we define MOs in the restricted case ... stopping")
486 ELSE
487 IF (dft_control%do_admm) THEN
488 IF (dft_control%do_admm_mo) THEN
489 cpabort("ADMM currently possible only with purification none_dm")
490 END IF
491 END IF
492
493 ALLOCATE (eigenvalues(nmo_occ, nspins))
494 eigenvalues = 0.0_dp
495 CALL get_qs_env(qs_env, matrix_ks=ks_matrix, matrix_s=s_matrix, scf_control=scf_control)
496
497 ! calculate virtual MOs and copy inactive and active orbitals
498 IF (iw > 0) THEN
499 WRITE (iw, '(/,T3,A)') "Calculating virtual MOs..."
500 END IF
501 DO ispin = 1, nspins
502 ! nmo_available is the number of MOs available from the SCF calculation:
503 ! this is at least the number of occupied orbitals in the SCF, plus
504 ! any number of added MOs (virtuals) requested in the SCF section
505 CALL get_mo_set(mos(ispin), mo_coeff=mo_ref, nmo=nmo_available)
506
507 ! calculate how many extra MOs we still have to compute
508 nmo_virtual = nmo_occ - nmo_available
509 nmo_virtual = max(nmo_virtual, 0)
510
511 NULLIFY (evals_virtual)
512 ALLOCATE (evals_virtual(nmo_virtual))
513
514 CALL cp_fm_get_info(mo_ref, context=context, para_env=para_env, &
515 nrow_global=nrow_global)
516
517 CALL cp_fm_struct_create(fm_struct_tmp, para_env=para_env, context=context, &
518 nrow_global=nrow_global, ncol_global=nmo_virtual)
519 CALL cp_fm_create(mo_virtual, fm_struct_tmp, name="virtual")
520 CALL cp_fm_struct_release(fm_struct_tmp)
521 CALL cp_fm_init_random(mo_virtual, nmo_virtual)
522
523 NULLIFY (local_preconditioner)
524
525 ! compute missing virtual MOs
526 CALL ot_eigensolver(matrix_h=ks_matrix(ispin)%matrix, matrix_s=s_matrix(1)%matrix, &
527 matrix_c_fm=mo_virtual, matrix_orthogonal_space_fm=mo_ref, &
528 eps_gradient=scf_control%eps_lumos, &
529 preconditioner=local_preconditioner, &
530 iter_max=scf_control%max_iter_lumos, &
531 size_ortho_space=nmo_available)
532
533 ! get the eigenvalues
534 CALL calculate_subspace_eigenvalues(mo_virtual, ks_matrix(ispin)%matrix, evals_virtual)
535
536 ! we need to send the copy of MOs to preserve the sign
537 CALL cp_fm_create(fm_dummy, mo_ref%matrix_struct)
538 CALL cp_fm_to_fm(mo_ref, fm_dummy)
539 CALL calculate_subspace_eigenvalues(fm_dummy, ks_matrix(ispin)%matrix, &
540 evals_arg=eigenvalues(:, ispin), do_rotation=.true.)
541
542 ! copy inactive orbitals
543 mo_set => active_space_env%mos_inactive(ispin)
544 CALL get_mo_set(mo_set, mo_coeff=mo_target)
545 DO i = 1, SIZE(active_space_env%inactive_orbitals, 1)
546 m = active_space_env%inactive_orbitals(i, ispin)
547 CALL cp_fm_to_fm(mo_ref, mo_target, 1, m, m)
548 mo_set%eigenvalues(m) = eigenvalues(m, ispin)
549 IF (nspins > 1) THEN
550 mo_set%occupation_numbers(m) = 1.0
551 ELSE
552 mo_set%occupation_numbers(m) = 2.0
553 END IF
554 END DO
555
556 ! copy active orbitals
557 mo_set => active_space_env%mos_active(ispin)
558 CALL get_mo_set(mo_set, mo_coeff=mo_target)
559 ! for mult > 1, put the polarized electrons in the alpha channel
560 IF (nspins == 2) THEN
561 IF (ispin == 1) THEN
562 nel = (nelec_active + active_space_env%multiplicity - 1)/2
563 ELSE
564 nel = (nelec_active - active_space_env%multiplicity + 1)/2
565 END IF
566 ELSE
567 nel = nelec_active
568 END IF
569 mo_set%nelectron = nel
570 mo_set%n_el_f = real(nel, kind=dp)
571 DO i = 1, nmo_active
572 m = active_space_env%active_orbitals(i, ispin)
573 IF (m > nmo_available) THEN
574 CALL cp_fm_to_fm(mo_virtual, mo_target, 1, m - nmo_available, m)
575 eigenvalues(m, ispin) = evals_virtual(m - nmo_available)
576 mo_set%occupation_numbers(m) = 0.0
577 ELSE
578 CALL cp_fm_to_fm(mo_ref, mo_target, 1, m, m)
579 mo_set%occupation_numbers(m) = mos(ispin)%occupation_numbers(m)
580 END IF
581 mo_set%eigenvalues(m) = eigenvalues(m, ispin)
582 END DO
583 ! Release
584 DEALLOCATE (evals_virtual)
585 CALL cp_fm_release(fm_dummy)
586 CALL cp_fm_release(mo_virtual)
587 END DO
588
589 IF (iw > 0) THEN
590 DO ispin = 1, nspins
591 WRITE (iw, '(/,T3,A,I3,T66,A)') "Canonical Orbital Selection for spin", ispin, &
592 "[atomic units]"
593 DO i = 1, nmo_inactive, 4
594 jm = min(3, nmo_inactive - i)
595 WRITE (iw, '(T3,4(F14.6,A5))') (eigenvalues(i + j, ispin), " [I]", j=0, jm)
596 END DO
597 DO i = nmo_inactive + 1, nmo_inactive + nmo_active, 4
598 jm = min(3, nmo_inactive + nmo_active - i)
599 WRITE (iw, '(T3,4(F14.6,A5))') (eigenvalues(i + j, ispin), " [A]", j=0, jm)
600 END DO
601 WRITE (iw, '(/,T3,A,I3)') "Active Orbital Indices for spin", ispin
602 DO i = 1, SIZE(active_space_env%active_orbitals, 1), 4
603 jm = min(3, SIZE(active_space_env%active_orbitals, 1) - i)
604 WRITE (iw, '(T3,4(I4))') (active_space_env%active_orbitals(i + j, ispin), j=0, jm)
605 END DO
606 END DO
607 END IF
608 DEALLOCATE (eigenvalues)
609 END IF
610
611 CASE (manual_selection)
612 ! create canonical orbitals
613 IF (dft_control%restricted) THEN
614 cpabort("Unclear how we define MOs in the restricted case ... stopping")
615 ELSE
616 IF (dft_control%do_admm) THEN
617 ! For admm_mo, the auxiliary density is computed from the MOs, which never change
618 ! in the rs-dft embedding, therefore the energy is wrong as the LR HFX never changes.
619 ! For admm_dm, the auxiliary density is computed from the density matrix, which is
620 ! updated at each iteration and therefore works.
621 IF (dft_control%do_admm_mo) THEN
622 cpabort("ADMM currently possible only with purification none_dm")
623 END IF
624 END IF
625
626 CALL section_vals_val_get(as_input, "ACTIVE_ORBITAL_INDICES", explicit=explicit, i_vals=invals)
627 IF (.NOT. explicit) THEN
628 CALL cp_abort(__location__, "Manual orbital selection requires to explicitly "// &
629 "set the active orbital indices via ACTIVE_ORBITAL_INDICES")
630 END IF
631
632 IF (nspins == 1) THEN
633 cpassert(SIZE(invals) == nmo_active)
634 ELSE
635 cpassert(SIZE(invals) == 2*nmo_active)
636 END IF
637 ALLOCATE (active_space_env%inactive_orbitals(nmo_inactive, nspins))
638 ALLOCATE (active_space_env%active_orbitals(nmo_active, nspins))
639
640 DO ispin = 1, nspins
641 DO i = 1, nmo_active
642 active_space_env%active_orbitals(i, ispin) = invals(i + (ispin - 1)*nmo_active)
643 END DO
644 END DO
645
646 CALL get_qs_env(qs_env, mos=mos)
647
648 ! include MOs up to the largest index in the list
649 max_orb_ind = maxval(invals)
650 maxocc = 2.0_dp
651 IF (nspins > 1) maxocc = 1.0_dp
652 ALLOCATE (active_space_env%mos_active(nspins))
653 ALLOCATE (active_space_env%mos_inactive(nspins))
654 DO ispin = 1, nspins
655 ! init active orbitals
656 CALL get_mo_set(mos(ispin), mo_coeff=mo_ref, nao=nao)
657 CALL cp_fm_get_info(mo_ref, context=context, para_env=para_env, nrow_global=nrow_global)
658 CALL allocate_mo_set(active_space_env%mos_active(ispin), nao, max_orb_ind, 0, 0.0_dp, maxocc, 0.0_dp)
659 CALL cp_fm_struct_create(fm_struct_tmp, para_env=para_env, context=context, &
660 nrow_global=nrow_global, ncol_global=max_orb_ind)
661 CALL init_mo_set(active_space_env%mos_active(ispin), fm_struct=fm_struct_tmp, name="Active Space MO")
662 CALL cp_fm_struct_release(fm_struct_tmp)
663
664 ! init inactive orbitals
665 IF (nspins == 2) THEN
666 nel = nelec_inactive/2
667 ELSE
668 nel = nelec_inactive
669 END IF
670 CALL allocate_mo_set(active_space_env%mos_inactive(ispin), nao, max_orb_ind, nel, real(nel, kind=dp), maxocc, 0.0_dp)
671 CALL cp_fm_struct_create(fm_struct_tmp, para_env=para_env, context=context, &
672 nrow_global=nrow_global, ncol_global=max_orb_ind)
673 CALL init_mo_set(active_space_env%mos_inactive(ispin), fm_struct=fm_struct_tmp, name="Inactive Space MO")
674 ! small hack: set the correct inactive occupations down below
675 active_space_env%mos_inactive(ispin)%occupation_numbers = 0.0_dp
676 CALL cp_fm_struct_release(fm_struct_tmp)
677 END DO
678
679 ALLOCATE (eigenvalues(max_orb_ind, nspins))
680 eigenvalues = 0.0_dp
681 CALL get_qs_env(qs_env, matrix_ks=ks_matrix, matrix_s=s_matrix, scf_control=scf_control)
682
683 ! calculate virtual MOs and copy inactive and active orbitals
684 IF (iw > 0) THEN
685 WRITE (iw, '(/,T3,A)') "Calculating virtual MOs..."
686 END IF
687 DO ispin = 1, nspins
688 CALL get_mo_set(mos(ispin), mo_coeff=mo_ref, nmo=nmo_available)
689 nmo_virtual = max_orb_ind - nmo_available
690 nmo_virtual = max(nmo_virtual, 0)
691
692 NULLIFY (evals_virtual)
693 ALLOCATE (evals_virtual(nmo_virtual))
694
695 CALL cp_fm_get_info(mo_ref, context=context, para_env=para_env, &
696 nrow_global=nrow_global)
697
698 CALL cp_fm_struct_create(fm_struct_tmp, para_env=para_env, context=context, &
699 nrow_global=nrow_global, ncol_global=nmo_virtual)
700 CALL cp_fm_create(mo_virtual, fm_struct_tmp, name="virtual")
701 CALL cp_fm_struct_release(fm_struct_tmp)
702 CALL cp_fm_init_random(mo_virtual, nmo_virtual)
703
704 NULLIFY (local_preconditioner)
705
706 CALL ot_eigensolver(matrix_h=ks_matrix(ispin)%matrix, matrix_s=s_matrix(1)%matrix, &
707 matrix_c_fm=mo_virtual, matrix_orthogonal_space_fm=mo_ref, &
708 eps_gradient=scf_control%eps_lumos, &
709 preconditioner=local_preconditioner, &
710 iter_max=scf_control%max_iter_lumos, &
711 size_ortho_space=nmo_available)
712
713 CALL calculate_subspace_eigenvalues(mo_virtual, ks_matrix(ispin)%matrix, &
714 evals_virtual)
715
716 ! We need to send the copy of MOs to preserve the sign
717 CALL cp_fm_create(fm_dummy, mo_ref%matrix_struct)
718 CALL cp_fm_to_fm(mo_ref, fm_dummy)
719
720 CALL calculate_subspace_eigenvalues(fm_dummy, ks_matrix(ispin)%matrix, &
721 evals_arg=eigenvalues(:, ispin), do_rotation=.true.)
722
723 mo_set_active => active_space_env%mos_active(ispin)
724 CALL get_mo_set(mo_set_active, mo_coeff=fm_target_active)
725 mo_set_inactive => active_space_env%mos_inactive(ispin)
726 CALL get_mo_set(mo_set_inactive, mo_coeff=fm_target_inactive)
727
728 ! copy orbitals
729 nmo_inactive_remaining = nmo_inactive
730 DO i = 1, max_orb_ind
731 ! case for i being an active orbital
732 IF (any(active_space_env%active_orbitals(:, ispin) == i)) THEN
733 IF (i > nmo_available) THEN
734 CALL cp_fm_to_fm(mo_virtual, fm_target_active, 1, i - nmo_available, i)
735 eigenvalues(i, ispin) = evals_virtual(i - nmo_available)
736 mo_set_active%occupation_numbers(i) = 0.0
737 ELSE
738 CALL cp_fm_to_fm(fm_dummy, fm_target_active, 1, i, i)
739 mo_set_active%occupation_numbers(i) = mos(ispin)%occupation_numbers(i)
740 END IF
741 mo_set_active%eigenvalues(i) = eigenvalues(i, ispin)
742 ! if it was not an active orbital, check whether it is an inactive orbital
743 ELSEIF (nmo_inactive_remaining > 0) THEN
744 CALL cp_fm_to_fm(fm_dummy, fm_target_inactive, 1, i, i)
745 ! store on the fly the mapping of inactive orbitals
746 active_space_env%inactive_orbitals(nmo_inactive - nmo_inactive_remaining + 1, ispin) = i
747 mo_set_inactive%eigenvalues(i) = eigenvalues(i, ispin)
748 mo_set_inactive%occupation_numbers(i) = mos(ispin)%occupation_numbers(i)
749 ! hack: set homo and lumo manually
750 IF (nmo_inactive_remaining == 1) THEN
751 mo_set_inactive%homo = i
752 mo_set_inactive%lfomo = i + 1
753 END IF
754 nmo_inactive_remaining = nmo_inactive_remaining - 1
755 ELSE
756 cycle
757 END IF
758 END DO
759
760 ! Release
761 DEALLOCATE (evals_virtual)
762 CALL cp_fm_release(fm_dummy)
763 CALL cp_fm_release(mo_virtual)
764 END DO
765
766 IF (iw > 0) THEN
767 DO ispin = 1, nspins
768 WRITE (iw, '(/,T3,A,I3,T66,A)') "Orbital Energies and Selection for spin", ispin, "[atomic units]"
769
770 DO i = 1, max_orb_ind, 4
771 jm = min(3, max_orb_ind - i)
772 WRITE (iw, '(T4)', advance="no")
773 DO j = 0, jm
774 IF (any(active_space_env%active_orbitals(:, ispin) == i + j)) THEN
775 WRITE (iw, '(T3,F12.6,A5)', advance="no") eigenvalues(i + j, ispin), " [A]"
776 ELSEIF (any(active_space_env%inactive_orbitals(:, ispin) == i + j)) THEN
777 WRITE (iw, '(T3,F12.6,A5)', advance="no") eigenvalues(i + j, ispin), " [I]"
778 ELSE
779 WRITE (iw, '(T3,F12.6,A5)', advance="no") eigenvalues(i + j, ispin), " [V]"
780 END IF
781 END DO
782 WRITE (iw, *)
783 END DO
784 WRITE (iw, '(/,T3,A,I3)') "Active Orbital Indices for spin", ispin
785 DO i = 1, SIZE(active_space_env%active_orbitals, 1), 4
786 jm = min(3, SIZE(active_space_env%active_orbitals, 1) - i)
787 WRITE (iw, '(T3,4(I4))') (active_space_env%active_orbitals(i + j, ispin), j=0, jm)
788 END DO
789 END DO
790 END IF
791 DEALLOCATE (eigenvalues)
792 END IF
793
794 CASE (wannier_projection)
795 NULLIFY (loc_section, loc_print)
796 loc_section => section_vals_get_subs_vals(as_input, "LOCALIZE")
797 cpassert(ASSOCIATED(loc_section))
798 loc_print => section_vals_get_subs_vals(as_input, "LOCALIZE%PRINT")
799 !
800 cpabort("not yet available")
801 !
802 CASE (mao_projection)
803 !
804 cpabort("not yet available")
805 !
806 END SELECT
807
808 ! Print orbitals on Cube files
809 print_orb => section_vals_get_subs_vals(as_input, "PRINT_ORBITAL_CUBES")
810 CALL section_vals_get(print_orb, explicit=explicit)
811 CALL section_vals_val_get(print_orb, "STOP_AFTER_CUBES", l_val=stop_after_print)
812 IF (explicit) THEN
813 !
814 CALL print_orbital_cubes(print_orb, qs_env, active_space_env%mos_active)
815 !
816 IF (stop_after_print) THEN
817
818 IF (iw > 0) THEN
819 WRITE (iw, '(/,T2,A)') &
820 '!----------------- Early End of Active Space Interface -----------------------!'
821 END IF
822
823 CALL timestop(handle)
824
825 RETURN
826 END IF
827 END IF
828
829 ! calculate inactive density matrix
830 CALL get_qs_env(qs_env, rho=rho)
831 CALL qs_rho_get(rho, rho_ao=rho_ao)
832 cpassert(ASSOCIATED(rho_ao))
833 CALL dbcsr_allocate_matrix_set(active_space_env%pmat_inactive, nspins)
834 DO ispin = 1, nspins
835 ALLOCATE (denmat)
836 CALL dbcsr_copy(denmat, rho_ao(ispin)%matrix)
837 mo_set => active_space_env%mos_inactive(ispin)
838 CALL calculate_density_matrix(mo_set, denmat)
839 active_space_env%pmat_inactive(ispin)%matrix => denmat
840 END DO
841
842 ! read in ERI parameters
843 CALL section_vals_val_get(as_input, "ERI%METHOD", i_val=eri_method)
844 active_space_env%eri%method = eri_method
845 CALL section_vals_val_get(as_input, "ERI%OPERATOR", i_val=eri_operator, explicit=ex_operator)
846 active_space_env%eri%operator = eri_operator
847 CALL section_vals_val_get(as_input, "ERI%OMEGA", r_val=eri_op_omega, explicit=ex_omega)
848 active_space_env%eri%omega = eri_op_omega
849 CALL section_vals_val_get(as_input, "ERI%CUTOFF_RADIUS", r_val=eri_rcut, explicit=ex_rcut)
850 active_space_env%eri%cutoff_radius = eri_rcut ! this is already converted to bohr!
851 CALL section_vals_val_get(as_input, "ERI%PERIODICITY", i_vals=invals, explicit=ex_perd)
852 CALL section_vals_val_get(as_input, "ERI%EPS_INTEGRAL", r_val=eri_eps_int)
853 active_space_env%eri%eps_integral = eri_eps_int
854 ! if eri periodicity is explicitly set, we use it, otherwise we use the cell periodicity
855 IF (ex_perd) THEN
856 IF (SIZE(invals) == 1) THEN
857 active_space_env%eri%periodicity(1:3) = invals(1)
858 ELSE
859 active_space_env%eri%periodicity(1:3) = invals(1:3)
860 END IF
861 ELSE
862 CALL get_qs_env(qs_env, cell=cell)
863 active_space_env%eri%periodicity(1:3) = cell%perd(1:3)
864 END IF
865 IF (iw > 0) THEN
866 WRITE (iw, '(/,T3,A)') "Calculation of Electron Repulsion Integrals"
867
868 SELECT CASE (eri_method)
870 WRITE (iw, '(T3,A,T50,A)') "Integration method", "GPW Fourier transform over MOs"
871 CASE (eri_method_gpw_ht)
872 WRITE (iw, '(T3,A,T44,A)') "Integration method", "Half transformed integrals from GPW"
873 CASE DEFAULT
874 cpabort("Unknown ERI method")
875 END SELECT
876
877 SELECT CASE (eri_operator)
879 WRITE (iw, '(T3,A,T73,A)') "ERI operator", "Coulomb"
880
882 WRITE (iw, '(T3,A,T74,A)') "ERI operator", "Yukawa"
883 IF (.NOT. ex_omega) CALL cp_abort(__location__, &
884 "Yukawa operator requires OMEGA to be explicitly set")
885 WRITE (iw, '(T3,A,T66,F14.3)') "ERI operator parameter OMEGA", eri_op_omega
886
887 CASE (eri_operator_erf)
888 WRITE (iw, '(T3,A,T63,A)') "ERI operator", "Longrange Coulomb"
889 IF (.NOT. ex_omega) CALL cp_abort(__location__, &
890 "Longrange operator requires OMEGA to be explicitly set")
891 WRITE (iw, '(T3,A,T66,F14.3)') "ERI operator parameter OMEGA", eri_op_omega
892
893 CASE (eri_operator_erfc)
894 WRITE (iw, '(T3,A,T62,A)') "ERI operator", "Shortrange Coulomb"
895 IF (.NOT. ex_omega) CALL cp_abort(__location__, &
896 "Shortrange operator requires OMEGA to be explicitly set")
897 WRITE (iw, '(T3,A,T66,F14.3)') "ERI operator parameter OMEGA", eri_op_omega
898
899 CASE (eri_operator_trunc)
900 WRITE (iw, '(T3,A,T63,A)') "ERI operator", "Truncated Coulomb"
901 IF (.NOT. ex_rcut) CALL cp_abort(__location__, &
902 "Cutoff radius not specified for trunc. Coulomb operator")
903 WRITE (iw, '(T3,A,T66,F14.3)') "ERI operator cutoff radius (au)", eri_rcut
904
906 WRITE (iw, '(T3,A,T53,A)') "ERI operator", "Longrange truncated Coulomb"
907 IF (.NOT. ex_rcut) CALL cp_abort(__location__, &
908 "Cutoff radius not specified for trunc. longrange operator")
909 WRITE (iw, '(T3,A,T66,F14.3)') "ERI operator cutoff radius (au)", eri_rcut
910 IF (.NOT. ex_omega) CALL cp_abort(__location__, &
911 "LR truncated operator requires OMEGA to be explicitly set")
912 WRITE (iw, '(T3,A,T66,F14.3)') "ERI operator parameter OMEGA", eri_op_omega
913 IF (eri_op_omega < 0.01_dp) THEN
914 cpabort("LR truncated operator requires OMEGA >= 0.01 to be stable")
915 END IF
916
917 CASE DEFAULT
918 cpabort("Unknown ERI operator")
919
920 END SELECT
921
922 WRITE (iw, '(T3,A,T68,E12.4)') "Accuracy of ERIs", eri_eps_int
923 WRITE (iw, '(T3,A,T71,3I3)') "Periodicity", active_space_env%eri%periodicity(1:3)
924
925 ! TODO: should be moved after ERI calculation, as it depends on screening
926 IF (nspins < 2) THEN
927 WRITE (iw, '(T3,A,T68,I12)') "Total Number of ERI", (nmo_active**4)/8
928 ELSE
929 WRITE (iw, '(T3,A,T68,I12)') "Total Number of ERI (aa|aa)", (nmo_active**4)/8
930 WRITE (iw, '(T3,A,T68,I12)') "Total Number of ERI (bb|bb)", (nmo_active**4)/8
931 WRITE (iw, '(T3,A,T68,I12)') "Total Number of ERI (aa|bb)", (nmo_active**4)/4
932 END IF
933 END IF
934
935 ! allocate container for integrals (CSR matrix)
936 CALL get_qs_env(qs_env, para_env=para_env)
937 m = (nspins*(nspins + 1))/2
938 ALLOCATE (active_space_env%eri%eri(m))
939 DO i = 1, m
940 CALL get_mo_set(active_space_env%mos_active(1), nmo=nmo)
941 ALLOCATE (active_space_env%eri%eri(i)%csr_mat)
942 eri_mat => active_space_env%eri%eri(i)%csr_mat
943 IF (i == 1) THEN
944 n1 = nmo
945 n2 = nmo
946 ELSEIF (i == 2) THEN
947 n1 = nmo
948 n2 = nmo
949 ELSE
950 n1 = nmo
951 n2 = nmo
952 END IF
953 nn1 = (n1*(n1 + 1))/2
954 nn2 = (n2*(n2 + 1))/2
955 CALL dbcsr_csr_create(eri_mat, nn1, nn2, 0_int_8, 0, 0, para_env%get_handle())
956 active_space_env%eri%norb = nmo
957 END DO
958
959 SELECT CASE (eri_method)
961 CALL section_vals_val_get(as_input, "ERI_GPW%EPS_GRID", r_val=eri_eps_grid)
962 active_space_env%eri%eri_gpw%eps_grid = eri_eps_grid
963 CALL section_vals_val_get(as_input, "ERI_GPW%EPS_FILTER", r_val=eri_eps_filter)
964 active_space_env%eri%eri_gpw%eps_filter = eri_eps_filter
965 CALL section_vals_val_get(as_input, "ERI_GPW%CUTOFF", r_val=eri_gpw_cutoff)
966 active_space_env%eri%eri_gpw%cutoff = eri_gpw_cutoff
967 CALL section_vals_val_get(as_input, "ERI_GPW%REL_CUTOFF", r_val=eri_rel_cutoff)
968 active_space_env%eri%eri_gpw%rel_cutoff = eri_rel_cutoff
969 CALL section_vals_val_get(as_input, "ERI_GPW%PRINT_LEVEL", i_val=eri_print)
970 active_space_env%eri%eri_gpw%print_level = eri_print
971 CALL section_vals_val_get(as_input, "ERI_GPW%STORE_WFN", l_val=store_wfn)
972 active_space_env%eri%eri_gpw%store_wfn = store_wfn
973 CALL section_vals_val_get(as_input, "ERI_GPW%GROUP_SIZE", i_val=group_size)
974 active_space_env%eri%eri_gpw%group_size = group_size
975 ! Always redo Poisson solver for now
976 active_space_env%eri%eri_gpw%redo_poisson = .true.
977 ! active_space_env%eri%eri_gpw%redo_poisson = (ex_operator .OR. ex_perd)
978 IF (iw > 0) THEN
979 WRITE (iw, '(/,T2,A,T71,F10.1)') "ERI_GPW| Energy cutoff [Ry]", eri_gpw_cutoff
980 WRITE (iw, '(T2,A,T71,F10.1)') "ERI_GPW| Relative energy cutoff [Ry]", eri_rel_cutoff
981 END IF
982 !
983 CALL calculate_eri_gpw(active_space_env%mos_active, active_space_env%active_orbitals, active_space_env%eri, qs_env, iw)
984 !
985 CASE DEFAULT
986 cpabort("Unknown ERI method")
987 END SELECT
988 IF (iw > 0) THEN
989 DO isp = 1, SIZE(active_space_env%eri%eri)
990 eri_mat => active_space_env%eri%eri(isp)%csr_mat
991 nze_percentage = 100.0_dp*(real(eri_mat%nze_total, kind=dp) &
992 /real(eri_mat%nrows_total, kind=dp))/real(eri_mat%ncols_total, kind=dp)
993 WRITE (iw, '(/,T2,A,I2,T30,A,T68,I12)') "ERI_GPW| Spinmatrix:", isp, &
994 "Number of CSR non-zero elements:", eri_mat%nze_total
995 WRITE (iw, '(T2,A,I2,T30,A,T68,F12.4)') "ERI_GPW| Spinmatrix:", isp, &
996 "Percentage CSR non-zero elements:", nze_percentage
997 WRITE (iw, '(T2,A,I2,T30,A,T68,I12)') "ERI_GPW| Spinmatrix:", isp, &
998 "nrows_total", eri_mat%nrows_total
999 WRITE (iw, '(T2,A,I2,T30,A,T68,I12)') "ERI_GPW| Spinmatrix:", isp, &
1000 "ncols_total", eri_mat%ncols_total
1001 WRITE (iw, '(T2,A,I2,T30,A,T68,I12)') "ERI_GPW| Spinmatrix:", isp, &
1002 "nrows_local", eri_mat%nrows_local
1003 END DO
1004 END IF
1005
1006 ! set the reference active space density matrix
1007 nspins = active_space_env%nspins
1008 ALLOCATE (active_space_env%p_active(nspins))
1009 DO isp = 1, nspins
1010 mo_set => active_space_env%mos_active(isp)
1011 CALL get_mo_set(mo_set, mo_coeff=mo_coeff, nmo=nmo)
1012 CALL create_subspace_matrix(mo_coeff, active_space_env%p_active(isp), nmo)
1013 END DO
1014 SELECT CASE (mselect)
1015 CASE DEFAULT
1016 cpabort("Unknown orbital selection method")
1018 focc = 2.0_dp
1019 IF (nspins == 2) focc = 1.0_dp
1020 DO isp = 1, nspins
1021 fmat => active_space_env%p_active(isp)
1022 CALL cp_fm_set_all(fmat, alpha=0.0_dp)
1023 IF (nspins == 2) THEN
1024 IF (isp == 1) THEN
1025 nel = (active_space_env%nelec_active + active_space_env%multiplicity - 1)/2
1026 ELSE
1027 nel = (active_space_env%nelec_active - active_space_env%multiplicity + 1)/2
1028 END IF
1029 ELSE
1030 nel = active_space_env%nelec_active
1031 END IF
1032 DO i = 1, nmo_active
1033 m = active_space_env%active_orbitals(i, isp)
1034 fel = min(focc, real(nel, kind=dp))
1035 CALL cp_fm_set_element(fmat, m, m, fel)
1036 nel = nel - nint(fel)
1037 nel = max(nel, 0)
1038 END DO
1039 END DO
1040 CASE (wannier_projection)
1041 cpabort("NOT IMPLEMENTED")
1042 CASE (mao_projection)
1043 cpabort("NOT IMPLEMENTED")
1044 END SELECT
1045
1046 ! compute alpha-beta overlap matrix in case of spin-polarized calculation
1047 CALL calculate_spin_pol_overlap(active_space_env%mos_active, qs_env, active_space_env)
1048
1049 ! figure out if we have a new xc section for the AS
1050 xc_section => section_vals_get_subs_vals(input, "DFT%ACTIVE_SPACE%XC")
1051 explicit = .false.
1052 IF (ASSOCIATED(xc_section)) CALL section_vals_get(xc_section, explicit=explicit)
1053
1054 ! rebuild KS matrix if needed
1055 IF (explicit) THEN
1056 ! release the hfx data if it was part of the SCF functional
1057 IF (ASSOCIATED(qs_env%x_data)) CALL hfx_release(qs_env%x_data)
1058 ! also release the admm environment in case we are using admm
1059 IF (ASSOCIATED(qs_env%admm_env)) CALL admm_env_release(qs_env%admm_env)
1060
1061 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, qs_kind_set=qs_kind_set, &
1062 particle_set=particle_set, cell=cell, ks_env=ks_env)
1063 IF (dft_control%do_admm) THEN
1064 basis_type = 'AUX_FIT'
1065 ELSE
1066 basis_type = 'ORB'
1067 END IF
1068 hfx_section => section_vals_get_subs_vals(xc_section, "HF")
1069 CALL hfx_create(qs_env%x_data, para_env, hfx_section, atomic_kind_set, &
1070 qs_kind_set, particle_set, dft_control, cell, orb_basis=basis_type, &
1071 nelectron_total=nelec_total)
1072
1073 qs_env%requires_matrix_vxc = .true. ! needs to be set only once
1074
1075 ! a bit of a hack: this forces a new re-init of HFX
1076 CALL set_ks_env(ks_env, s_mstruct_changed=.true.)
1077 CALL qs_ks_build_kohn_sham_matrix(qs_env, calculate_forces=.false., &
1078 just_energy=.false., &
1079 ext_xc_section=xc_section)
1080 ! we need to reset it to false
1081 CALL set_ks_env(ks_env, s_mstruct_changed=.false.)
1082 ELSE
1083 xc_section => section_vals_get_subs_vals(input, "DFT%XC")
1084 END IF
1085 ! set the xc_section
1086 active_space_env%xc_section => xc_section
1087
1088 CALL get_qs_env(qs_env, energy=energy)
1089 ! transform KS/Fock, Vxc and Hcore to AS MO basis
1090 CALL calculate_operators(active_space_env%mos_active, qs_env, active_space_env)
1091 ! set the reference energy in the active space
1092 active_space_env%energy_ref = energy%total
1093 ! calculate inactive energy and embedding potential
1094 CALL subspace_fock_matrix(active_space_env)
1095
1096 ! associate the active space environment with the qs environment
1097 CALL set_qs_env(qs_env, active_space=active_space_env)
1098
1099 ! Perform the embedding calculation only if qiskit is specified
1100 CALL section_vals_val_get(as_input, "AS_SOLVER", i_val=as_solver)
1101 SELECT CASE (as_solver)
1102 CASE (no_solver)
1103 IF (iw > 0) THEN
1104 WRITE (iw, '(/,T3,A)') "No active space solver specified, skipping embedding calculation"
1105 END IF
1106 CASE (qiskit_solver)
1107 CALL rsdft_embedding(qs_env, active_space_env, as_input)
1108 CALL qs_scf_compute_properties(qs_env, wf_type="MC-DFT", do_mp2=.false.)
1109 CASE DEFAULT
1110 cpabort("Unknown active space solver")
1111 END SELECT
1112
1113 ! Output a FCIDUMP file if requested
1114 IF (active_space_env%fcidump) CALL fcidump(active_space_env, as_input)
1115
1116 ! Output a QCSchema file if requested
1117 IF (active_space_env%qcschema) THEN
1118 CALL qcschema_env_create(qcschema_env, qs_env)
1119 CALL qcschema_to_hdf5(qcschema_env, active_space_env%qcschema_filename)
1120 CALL qcschema_env_release(qcschema_env)
1121 END IF
1122
1123 IF (iw > 0) THEN
1124 WRITE (iw, '(/,T2,A)') &
1125 '!-------------------- End of Active Space Interface --------------------------!'
1126 END IF
1127
1128 CALL timestop(handle)
1129
1130 END SUBROUTINE active_space_main
1131
1132! **************************************************************************************************
1133!> \brief computes the alpha-beta overlap within the active subspace
1134!> \param mos the molecular orbital set within the active subspace
1135!> \param qs_env ...
1136!> \param active_space_env ...
1137!> \par History
1138!> 04.2016 created [JGH]
1139! **************************************************************************************************
1140 SUBROUTINE calculate_spin_pol_overlap(mos, qs_env, active_space_env)
1141
1142 TYPE(mo_set_type), DIMENSION(:), INTENT(IN) :: mos
1143 TYPE(qs_environment_type), POINTER :: qs_env
1144 TYPE(active_space_type), POINTER :: active_space_env
1145
1146 CHARACTER(len=*), PARAMETER :: routinen = 'calculate_spin_pol_overlap'
1147
1148 INTEGER :: handle, nmo, nspins
1149 TYPE(cp_fm_type), POINTER :: mo_coeff_a, mo_coeff_b
1150 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: s_matrix
1151
1152 CALL timeset(routinen, handle)
1153
1154 nspins = active_space_env%nspins
1155
1156 ! overlap in AO
1157 IF (nspins > 1) THEN
1158 CALL get_qs_env(qs_env, matrix_s=s_matrix)
1159 ALLOCATE (active_space_env%sab_sub(1))
1160
1161 CALL get_mo_set(mo_set=mos(1), mo_coeff=mo_coeff_a, nmo=nmo)
1162 CALL get_mo_set(mo_set=mos(2), mo_coeff=mo_coeff_b, nmo=nmo)
1163 CALL subspace_operator(mo_coeff_a, nmo, s_matrix(1)%matrix, active_space_env%sab_sub(1), mo_coeff_b)
1164 END IF
1165
1166 CALL timestop(handle)
1167
1168 END SUBROUTINE calculate_spin_pol_overlap
1169
1170! **************************************************************************************************
1171!> \brief computes the one-electron operators in the subspace of the provided orbital set
1172!> \param mos the molecular orbital set within the active subspace
1173!> \param qs_env ...
1174!> \param active_space_env ...
1175!> \par History
1176!> 04.2016 created [JGH]
1177! **************************************************************************************************
1178 SUBROUTINE calculate_operators(mos, qs_env, active_space_env)
1179
1180 TYPE(mo_set_type), DIMENSION(:), INTENT(IN) :: mos
1181 TYPE(qs_environment_type), POINTER :: qs_env
1182 TYPE(active_space_type), POINTER :: active_space_env
1183
1184 CHARACTER(len=*), PARAMETER :: routinen = 'calculate_operators'
1185
1186 INTEGER :: handle, ispin, nmo, nspins
1187 TYPE(cp_fm_type), POINTER :: mo_coeff
1188 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: h_matrix, ks_matrix
1189
1190 CALL timeset(routinen, handle)
1191
1192 nspins = active_space_env%nspins
1193
1194 ! Kohn-Sham / Fock operator
1195 CALL cp_fm_release(active_space_env%ks_sub)
1196 CALL get_qs_env(qs_env, matrix_ks_kp=ks_matrix)
1197 ALLOCATE (active_space_env%ks_sub(nspins))
1198 DO ispin = 1, nspins
1199 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, nmo=nmo)
1200 CALL subspace_operator(mo_coeff, nmo, ks_matrix(ispin, 1)%matrix, active_space_env%ks_sub(ispin))
1201 END DO
1202
1203 ! Core Hamiltonian
1204 CALL cp_fm_release(active_space_env%h_sub)
1205
1206 NULLIFY (h_matrix)
1207 CALL get_qs_env(qs_env=qs_env, matrix_h_kp=h_matrix)
1208 ALLOCATE (active_space_env%h_sub(nspins))
1209 DO ispin = 1, nspins
1210 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, nmo=nmo)
1211 CALL subspace_operator(mo_coeff, nmo, h_matrix(1, 1)%matrix, active_space_env%h_sub(ispin))
1212 END DO
1213
1214 CALL timestop(handle)
1215
1216 END SUBROUTINE calculate_operators
1217
1218! **************************************************************************************************
1219!> \brief computes a one-electron operator in the subspace of the provided orbital set
1220!> \param mo_coeff the orbital coefficient matrix
1221!> \param nmo the number of subspace orbitals
1222!> \param op_matrix operator matrix in AO basis
1223!> \param op_sub operator in orbital basis
1224!> \param mo_coeff_b the beta orbital coefficients
1225!> \par History
1226!> 04.2016 created [JGH]
1227! **************************************************************************************************
1228 SUBROUTINE subspace_operator(mo_coeff, nmo, op_matrix, op_sub, mo_coeff_b)
1229
1230 TYPE(cp_fm_type), INTENT(IN) :: mo_coeff
1231 INTEGER, INTENT(IN) :: nmo
1232 TYPE(dbcsr_type), POINTER :: op_matrix
1233 TYPE(cp_fm_type), INTENT(INOUT) :: op_sub
1234 TYPE(cp_fm_type), INTENT(IN), OPTIONAL :: mo_coeff_b
1235
1236 CHARACTER(len=*), PARAMETER :: routinen = 'subspace_operator'
1237
1238 INTEGER :: handle, ncol, nrow
1239 TYPE(cp_fm_type) :: vectors
1240
1241 CALL timeset(routinen, handle)
1242
1243 CALL cp_fm_get_info(matrix=mo_coeff, ncol_global=ncol, nrow_global=nrow)
1244 cpassert(nmo <= ncol)
1245
1246 IF (nmo > 0) THEN
1247 CALL cp_fm_create(vectors, mo_coeff%matrix_struct, "vectors")
1248 CALL create_subspace_matrix(mo_coeff, op_sub, nmo)
1249
1250 IF (PRESENT(mo_coeff_b)) THEN
1251 ! if beta orbitals are present, compute the cross alpha_beta term
1252 CALL cp_dbcsr_sm_fm_multiply(op_matrix, mo_coeff_b, vectors, nmo)
1253 ELSE
1254 ! otherwise the same spin, whatever that is
1255 CALL cp_dbcsr_sm_fm_multiply(op_matrix, mo_coeff, vectors, nmo)
1256 END IF
1257
1258 CALL parallel_gemm('T', 'N', nmo, nmo, nrow, 1.0_dp, mo_coeff, vectors, 0.0_dp, op_sub)
1259 CALL cp_fm_release(vectors)
1260 END IF
1261
1262 CALL timestop(handle)
1263
1264 END SUBROUTINE subspace_operator
1265
1266! **************************************************************************************************
1267!> \brief creates a matrix of subspace size
1268!> \param orbitals the orbital coefficient matrix
1269!> \param op_sub operator in orbital basis
1270!> \param n the number of orbitals
1271!> \par History
1272!> 04.2016 created [JGH]
1273! **************************************************************************************************
1274 SUBROUTINE create_subspace_matrix(orbitals, op_sub, n)
1275
1276 TYPE(cp_fm_type), INTENT(IN) :: orbitals
1277 TYPE(cp_fm_type), INTENT(OUT) :: op_sub
1278 INTEGER, INTENT(IN) :: n
1279
1280 TYPE(cp_fm_struct_type), POINTER :: fm_struct
1281
1282 IF (n > 0) THEN
1283
1284 NULLIFY (fm_struct)
1285 CALL cp_fm_struct_create(fm_struct, nrow_global=n, ncol_global=n, &
1286 para_env=orbitals%matrix_struct%para_env, &
1287 context=orbitals%matrix_struct%context)
1288 CALL cp_fm_create(op_sub, fm_struct, name="Subspace operator")
1289 CALL cp_fm_struct_release(fm_struct)
1290
1291 END IF
1292
1293 END SUBROUTINE create_subspace_matrix
1294
1295! **************************************************************************************************
1296!> \brief computes the electron repulsion integrals using the GPW technology
1297!> \param mos the molecular orbital set within the active subspace
1298!> \param orbitals ...
1299!> \param eri_env ...
1300!> \param qs_env ...
1301!> \param iw ...
1302!> \par History
1303!> 04.2016 created [JGH]
1304! **************************************************************************************************
1305 SUBROUTINE calculate_eri_gpw(mos, orbitals, eri_env, qs_env, iw)
1306
1307 TYPE(mo_set_type), DIMENSION(:), INTENT(IN) :: mos
1308 INTEGER, DIMENSION(:, :), POINTER :: orbitals
1309 TYPE(eri_type) :: eri_env
1310 TYPE(qs_environment_type), POINTER :: qs_env
1311 INTEGER, INTENT(IN) :: iw
1312
1313 CHARACTER(len=*), PARAMETER :: routinen = 'calculate_eri_gpw'
1314
1315 INTEGER :: col_local, color, handle, i1, i2, i3, i4, i_multigrid, icount2, intcount, &
1316 irange(2), isp, isp1, isp2, ispin, iwa1, iwa12, iwa2, iwb1, iwb12, iwb2, iwbs, iwbt, &
1317 iwfn, n_multigrid, ncol_global, ncol_local, nmm, nmo, nmo1, nmo2, nrow_global, &
1318 nrow_local, nspins, number_of_subgroups, nx, row_local, stored_integrals
1319 INTEGER, ALLOCATABLE, DIMENSION(:) :: eri_index
1320 INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
1321 LOGICAL :: print1, print2, &
1322 skip_load_balance_distributed
1323 REAL(kind=dp) :: dvol, erint, pair_int, &
1324 progression_factor, rc, rsize, t1, t2
1325 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: eri
1326 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1327 TYPE(cell_type), POINTER :: cell
1328 TYPE(cp_blacs_env_type), POINTER :: blacs_env, blacs_env_sub
1329 TYPE(cp_fm_struct_type), POINTER :: fm_struct
1330 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_matrix_pq_rnu, fm_matrix_pq_rs, &
1331 fm_mo_coeff_as
1332 TYPE(cp_fm_type), POINTER :: mo_coeff
1333 TYPE(dbcsr_p_type) :: mat_munu
1334 TYPE(dbcsr_type), ALLOCATABLE, DIMENSION(:) :: matrix_pq_rnu, mo_coeff_as
1335 TYPE(dft_control_type), POINTER :: dft_control
1336 TYPE(mp_para_env_type), POINTER :: para_env
1337 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1338 POINTER :: sab_orb_sub
1339 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1340 TYPE(pw_c1d_gs_type) :: pot_g, rho_g
1341 TYPE(pw_env_type), POINTER :: pw_env_sub
1342 TYPE(pw_poisson_type), POINTER :: poisson_env
1343 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
1344 TYPE(pw_r3d_rs_type) :: rho_r, wfn_r
1345 TYPE(pw_r3d_rs_type), ALLOCATABLE, &
1346 DIMENSION(:, :), TARGET :: wfn_a
1347 TYPE(pw_r3d_rs_type), POINTER :: wfn1, wfn2, wfn3, wfn4
1348 TYPE(qs_control_type), POINTER :: qs_control, qs_control_old
1349 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1350 TYPE(qs_ks_env_type), POINTER :: ks_env
1351 TYPE(task_list_type), POINTER :: task_list_sub
1352
1353 CALL timeset(routinen, handle)
1354
1355 IF (iw > 0) t1 = m_walltime()
1356
1357 ! print levels
1358 SELECT CASE (eri_env%eri_gpw%print_level)
1359 CASE (silent_print_level)
1360 print1 = .false.
1361 print2 = .false.
1362 CASE (low_print_level)
1363 print1 = .false.
1364 print2 = .false.
1365 CASE (medium_print_level)
1366 print1 = .true.
1367 print2 = .false.
1368 CASE (high_print_level)
1369 print1 = .true.
1370 print2 = .true.
1371 CASE (debug_print_level)
1372 print1 = .true.
1373 print2 = .true.
1374 CASE DEFAULT
1375 ! do nothing
1376 END SELECT
1377
1378 ! Check the input group
1379 CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
1380 IF (eri_env%eri_gpw%group_size <= 1) eri_env%eri_gpw%group_size = para_env%num_pe
1381 IF (mod(para_env%num_pe, eri_env%eri_gpw%group_size) /= 0) &
1382 cpabort("Group size must be a divisor of the total number of processes!")
1383 ! Create a new para_env or reuse the old one
1384 IF (eri_env%eri_gpw%group_size == para_env%num_pe) THEN
1385 eri_env%para_env_sub => para_env
1386 CALL eri_env%para_env_sub%retain()
1387 blacs_env_sub => blacs_env
1388 CALL blacs_env_sub%retain()
1389 number_of_subgroups = 1
1390 color = 0
1391 ELSE
1392 number_of_subgroups = para_env%num_pe/eri_env%eri_gpw%group_size
1393 color = para_env%mepos/eri_env%eri_gpw%group_size
1394 ALLOCATE (eri_env%para_env_sub)
1395 CALL eri_env%para_env_sub%from_split(para_env, color)
1396 NULLIFY (blacs_env_sub)
1397 CALL cp_blacs_env_create(blacs_env_sub, eri_env%para_env_sub, blacs_grid_square, .true.)
1398 END IF
1399 CALL eri_env%comm_exchange%from_split(para_env, eri_env%para_env_sub%mepos)
1400
1401 ! This should be done differently! Copied from MP2 code
1402 CALL get_qs_env(qs_env, dft_control=dft_control)
1403 ALLOCATE (qs_control)
1404 qs_control_old => dft_control%qs_control
1405 qs_control = qs_control_old
1406 dft_control%qs_control => qs_control
1407 progression_factor = qs_control%progression_factor
1408 n_multigrid = SIZE(qs_control%e_cutoff)
1409 nspins = SIZE(mos)
1410 ! Allocate new cutoffs (just in private qs_control, not in qs_control_old)
1411 ALLOCATE (qs_control%e_cutoff(n_multigrid))
1412
1413 qs_control%cutoff = eri_env%eri_gpw%cutoff*0.5_dp
1414 qs_control%e_cutoff(1) = qs_control%cutoff
1415 DO i_multigrid = 2, n_multigrid
1416 qs_control%e_cutoff(i_multigrid) = qs_control%e_cutoff(i_multigrid - 1) &
1417 /progression_factor
1418 END DO
1419 qs_control%relative_cutoff = eri_env%eri_gpw%rel_cutoff*0.5_dp
1420
1421 ! For now, we will distribute neighbor lists etc. within the global communicator
1422 CALL get_qs_env(qs_env, ks_env=ks_env)
1423 CALL create_mat_munu(mat_munu, qs_env, eri_env%eri_gpw%eps_grid, blacs_env_sub, sab_orb_sub=sab_orb_sub, &
1424 do_alloc_blocks_from_nbl=.true., dbcsr_sym_type=dbcsr_type_symmetric)
1425 CALL dbcsr_set(mat_munu%matrix, 0.0_dp)
1426
1427 ! Generate the appropriate pw_env
1428 NULLIFY (pw_env_sub)
1429 CALL pw_env_create(pw_env_sub)
1430 CALL pw_env_rebuild(pw_env_sub, qs_env, external_para_env=eri_env%para_env_sub)
1431 CALL pw_env_get(pw_env_sub, auxbas_pw_pool=auxbas_pw_pool, poisson_env=poisson_env)
1432
1433 ! TODO: maybe we can let `pw_env_rebuild` do what we manually overwrite here?
1434 IF (eri_env%eri_gpw%redo_poisson) THEN
1435 ! We need to rebuild the Poisson solver on the fly
1436 IF (sum(eri_env%periodicity) /= 0) THEN
1437 poisson_env%parameters%solver = pw_poisson_periodic
1438 ELSE
1439 poisson_env%parameters%solver = pw_poisson_analytic
1440 END IF
1441 poisson_env%parameters%periodic = eri_env%periodicity
1442
1443 ! Rebuilds the poisson green (influence) function according
1444 ! to the poisson solver and parameters set so far.
1445 ! Also sets the variable poisson_env%rebuild to .FALSE.
1446 CALL pw_poisson_rebuild(poisson_env)
1447
1448 ! set the cutoff radius for the Greens function in case we use ANALYTIC Poisson solver
1449 CALL get_qs_env(qs_env, cell=cell)
1450 rc = cell%hmat(1, 1)
1451 DO iwa1 = 1, 3
1452 ! TODO: I think this is not the largest possible radius inscribed in the cell
1453 rc = min(rc, 0.5_dp*cell%hmat(iwa1, iwa1))
1454 END DO
1455 poisson_env%green_fft%radius = rc
1456
1457 ! Overwrite the Greens function with the one we want
1458 CALL pw_eri_green_create(poisson_env%green_fft, eri_env)
1459
1460 IF (iw > 0) THEN
1461 CALL get_qs_env(qs_env, cell=cell)
1462 IF (sum(cell%perd) /= sum(eri_env%periodicity)) THEN
1463 IF (sum(eri_env%periodicity) /= 0) THEN
1464 WRITE (unit=iw, fmt="(/,T2,A,T51,A30)") &
1465 "ERI_GPW| Switching Poisson solver to", "PERIODIC"
1466 ELSE
1467 WRITE (unit=iw, fmt="(/,T2,A,T51,A30)") &
1468 "ERI_GPW| Switching Poisson solver to", "ANALYTIC"
1469 END IF
1470 END IF
1471 ! print out the Greens function to check it matches the Poisson solver
1472 SELECT CASE (poisson_env%green_fft%method)
1473 CASE (periodic3d)
1474 WRITE (unit=iw, fmt="(T2,A,T51,A30)") &
1475 "ERI_GPW| Poisson Greens function", "PERIODIC"
1476 CASE (analytic0d)
1477 WRITE (unit=iw, fmt="(T2,A,T51,A30)") &
1478 "ERI_GPW| Poisson Greens function", "ANALYTIC"
1479 WRITE (unit=iw, fmt="(T2,A,T71,F10.4)") "ERI_GPW| Poisson cutoff radius", &
1480 poisson_env%green_fft%radius*angstrom
1481 CASE DEFAULT
1482 cpabort("Wrong Greens function setup")
1483 END SELECT
1484 END IF
1485 END IF
1486
1487 ALLOCATE (mo_coeff_as(nspins), fm_mo_coeff_as(nspins))
1488 DO ispin = 1, nspins
1489 block
1490 REAL(kind=dp), DIMENSION(:, :), ALLOCATABLE :: c
1491 INTEGER :: nmo
1492 TYPE(group_dist_d1_type) :: gd_array
1493 TYPE(cp_fm_type), POINTER :: mo_coeff
1494 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, nmo=nmo)
1495 CALL grep_rows_in_subgroups(para_env, eri_env%para_env_sub, mo_coeff, gd_array, c)
1496
1497 CALL build_dbcsr_from_rows(eri_env%para_env_sub, mo_coeff_as(ispin), &
1498 c(:, :nmo), mat_munu%matrix, gd_array, eri_env%eri_gpw%eps_filter)
1499 CALL release_group_dist(gd_array)
1500 DEALLOCATE (c)
1501 END block
1502
1503 CALL dbcsr_get_info(mo_coeff_as(ispin), nfullrows_total=nrow_global, nfullcols_total=ncol_global)
1504
1505 NULLIFY (fm_struct)
1506 CALL cp_fm_struct_create(fm_struct, context=blacs_env_sub, para_env=eri_env%para_env_sub, &
1507 nrow_global=nrow_global, ncol_global=ncol_global)
1508 CALL cp_fm_create(fm_mo_coeff_as(ispin), fm_struct)
1509 CALL cp_fm_struct_release(fm_struct)
1510
1511 CALL copy_dbcsr_to_fm(mo_coeff_as(ispin), fm_mo_coeff_as(ispin))
1512 END DO
1513
1514 IF (eri_env%method == eri_method_gpw_ht) THEN
1515 ! We need a task list
1516 NULLIFY (task_list_sub)
1517 skip_load_balance_distributed = dft_control%qs_control%skip_load_balance_distributed
1518 CALL allocate_task_list(task_list_sub)
1519 CALL generate_qs_task_list(ks_env, task_list_sub, basis_type="ORB", &
1520 reorder_rs_grid_ranks=.true., &
1521 skip_load_balance_distributed=skip_load_balance_distributed, &
1522 pw_env_external=pw_env_sub, sab_orb_external=sab_orb_sub)
1523
1524 ! Create sparse matrices carrying the matrix products, Code borrowed from the MP2 GPW method
1525 ! Create equal distributions for them (no sparsity present)
1526 ! We use the routines from mp2 suggesting that one may replicate the grids later for better performance
1527 ALLOCATE (matrix_pq_rnu(nspins), fm_matrix_pq_rnu(nspins), fm_matrix_pq_rs(nspins))
1528 DO ispin = 1, nspins
1529 CALL dbcsr_create(matrix_pq_rnu(ispin), template=mo_coeff_as(ispin))
1530 CALL dbcsr_set(matrix_pq_rnu(ispin), 0.0_dp)
1531
1532 CALL dbcsr_get_info(matrix_pq_rnu(ispin), nfullrows_total=nrow_global, nfullcols_total=ncol_global)
1533
1534 NULLIFY (fm_struct)
1535 CALL cp_fm_struct_create(fm_struct, context=blacs_env_sub, para_env=eri_env%para_env_sub, &
1536 nrow_global=nrow_global, ncol_global=ncol_global)
1537 CALL cp_fm_create(fm_matrix_pq_rnu(ispin), fm_struct)
1538 CALL cp_fm_struct_release(fm_struct)
1539
1540 NULLIFY (fm_struct)
1541 CALL cp_fm_struct_create(fm_struct, context=blacs_env_sub, para_env=eri_env%para_env_sub, &
1542 nrow_global=ncol_global, ncol_global=ncol_global)
1543 CALL cp_fm_create(fm_matrix_pq_rs(ispin), fm_struct)
1544 CALL cp_fm_struct_release(fm_struct)
1545 END DO
1546
1547 ! Copy the active space of the MOs into DBCSR matrices
1548 END IF
1549
1550 CALL auxbas_pw_pool%create_pw(wfn_r)
1551 CALL auxbas_pw_pool%create_pw(rho_g)
1552 CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set, cell=cell, &
1553 particle_set=particle_set, atomic_kind_set=atomic_kind_set)
1554
1555 ! pre-calculate wavefunctions on reals space grid
1556 nspins = SIZE(mos)
1557 IF (eri_env%eri_gpw%store_wfn) THEN
1558 ! pre-calculate wavefunctions on reals space grid
1559 rsize = 0.0_dp
1560 nmo = 0
1561 DO ispin = 1, nspins
1562 CALL get_mo_set(mo_set=mos(ispin), nmo=nx)
1563 nmo = max(nmo, nx)
1564 rsize = real(SIZE(wfn_r%array), kind=dp)*nx
1565 END DO
1566 IF (print1 .AND. iw > 0) THEN
1567 rsize = rsize*8._dp/1000000._dp
1568 WRITE (iw, "(T2,'ERI_GPW|',' Store active orbitals on real space grid ',T66,F12.3,' MB')") rsize
1569 END IF
1570 ALLOCATE (wfn_a(nmo, nspins))
1571 DO ispin = 1, nspins
1572 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, nmo=nmo)
1573 DO i1 = 1, SIZE(orbitals, 1)
1574 iwfn = orbitals(i1, ispin)
1575 CALL auxbas_pw_pool%create_pw(wfn_a(iwfn, ispin))
1576 CALL calculate_wavefunction(mo_coeff, iwfn, wfn_a(iwfn, ispin), rho_g, atomic_kind_set, &
1577 qs_kind_set, cell, dft_control, particle_set, pw_env_sub)
1578 IF (print2 .AND. iw > 0) THEN
1579 WRITE (iw, "(T2,'ERI_GPW|',' Orbital stored ',I4,' Spin ',i1)") iwfn, ispin
1580 END IF
1581 END DO
1582 END DO
1583 ELSE
1584 ! Even if we do not store all WFNs, we still need containers for the functions to store
1585 ALLOCATE (wfn1, wfn2)
1586 CALL auxbas_pw_pool%create_pw(wfn1)
1587 CALL auxbas_pw_pool%create_pw(wfn2)
1588 IF (eri_env%method /= eri_method_gpw_ht) THEN
1589 ALLOCATE (wfn3, wfn4)
1590 CALL auxbas_pw_pool%create_pw(wfn3)
1591 CALL auxbas_pw_pool%create_pw(wfn4)
1592 END IF
1593 END IF
1594
1595 ! get some of the grids ready
1596 CALL auxbas_pw_pool%create_pw(rho_r)
1597 CALL auxbas_pw_pool%create_pw(pot_g)
1598
1599 ! run the FFT once, to set up buffers and to take into account the memory
1600 CALL pw_zero(rho_r)
1601 CALL pw_transfer(rho_r, rho_g)
1602 dvol = rho_r%pw_grid%dvol
1603
1604 IF (iw > 0) THEN
1605 CALL m_flush(iw)
1606 END IF
1607 ! calculate the integrals
1608 stored_integrals = 0
1609 DO isp1 = 1, nspins
1610 CALL get_mo_set(mo_set=mos(isp1), nmo=nmo1)
1611 nmm = (nmo1*(nmo1 + 1))/2
1612 irange = get_irange_csr(nmm, eri_env%comm_exchange)
1613 DO i1 = 1, SIZE(orbitals, 1)
1614 iwa1 = orbitals(i1, isp1)
1615 IF (eri_env%eri_gpw%store_wfn) THEN
1616 wfn1 => wfn_a(iwa1, isp1)
1617 ELSE
1618 CALL calculate_wavefunction(fm_mo_coeff_as(isp1), iwa1, wfn1, rho_g, atomic_kind_set, &
1619 qs_kind_set, cell, dft_control, particle_set, pw_env_sub)
1620 END IF
1621 DO i2 = i1, SIZE(orbitals, 1)
1622 iwa2 = orbitals(i2, isp1)
1623 iwa12 = csr_idx_to_combined(iwa1, iwa2, nmo1)
1624 ! Skip calculation directly if the pair is not part of our subgroup
1625 IF (iwa12 < irange(1) .OR. iwa12 > irange(2)) cycle
1626 iwa12 = iwa12 - irange(1) + 1
1627 IF (eri_env%eri_gpw%store_wfn) THEN
1628 wfn2 => wfn_a(iwa2, isp1)
1629 ELSE
1630 CALL calculate_wavefunction(fm_mo_coeff_as(isp1), iwa2, wfn2, rho_g, atomic_kind_set, &
1631 qs_kind_set, cell, dft_control, particle_set, pw_env_sub)
1632 END IF
1633 ! calculate charge distribution and potential
1634 CALL pw_zero(rho_r)
1635 CALL pw_multiply(rho_r, wfn1, wfn2)
1636 CALL pw_transfer(rho_r, rho_g)
1637 CALL pw_poisson_solve(poisson_env, rho_g, pair_int, pot_g)
1638
1639 ! screening using pair_int
1640 IF (pair_int < eri_env%eps_integral) cycle
1641 CALL pw_transfer(pot_g, rho_r)
1642 !
1643 IF (eri_env%method == eri_method_gpw_ht) THEN
1644 CALL pw_scale(rho_r, dvol)
1645 DO isp2 = isp1, nspins
1646 CALL get_mo_set(mo_set=mos(isp2), nmo=nmo2)
1647 nx = (nmo2*(nmo2 + 1))/2
1648 ALLOCATE (eri(nx), eri_index(nx))
1649 CALL dbcsr_set(mat_munu%matrix, 0.0_dp)
1650 CALL integrate_v_rspace(rho_r, hmat=mat_munu, qs_env=qs_env, &
1651 calculate_forces=.false., compute_tau=.false., gapw=.false., &
1652 pw_env_external=pw_env_sub, task_list_external=task_list_sub)
1653
1654 CALL dbcsr_multiply("N", "N", 1.0_dp, mat_munu%matrix, mo_coeff_as(isp2), &
1655 0.0_dp, matrix_pq_rnu(isp2), filter_eps=eri_env%eri_gpw%eps_filter)
1656 CALL copy_dbcsr_to_fm(matrix_pq_rnu(isp2), fm_matrix_pq_rnu(isp2))
1657
1658 CALL cp_fm_get_info(fm_matrix_pq_rnu(isp2), ncol_global=ncol_global, nrow_global=nrow_global)
1659
1660 CALL parallel_gemm("T", "N", ncol_global, ncol_global, nrow_global, 0.5_dp, &
1661 fm_matrix_pq_rnu(isp2), fm_mo_coeff_as(isp2), &
1662 0.0_dp, fm_matrix_pq_rs(isp2))
1663 CALL parallel_gemm("T", "N", ncol_global, ncol_global, nrow_global, 0.5_dp, &
1664 fm_mo_coeff_as(isp2), fm_matrix_pq_rnu(isp2), &
1665 1.0_dp, fm_matrix_pq_rs(isp2))
1666
1667 CALL cp_fm_get_info(fm_matrix_pq_rs(isp2), ncol_local=ncol_local, nrow_local=nrow_local, &
1668 col_indices=col_indices, row_indices=row_indices)
1669
1670 icount2 = 0
1671 DO col_local = 1, ncol_local
1672 iwb2 = orbitals(col_indices(col_local), isp2)
1673 DO row_local = 1, nrow_local
1674 iwb1 = orbitals(row_indices(row_local), isp2)
1675
1676 IF (iwb1 <= iwb2) THEN
1677 iwb12 = csr_idx_to_combined(iwb1, iwb2, nmo2)
1678 erint = fm_matrix_pq_rs(isp2)%local_data(row_local, col_local)
1679 IF (abs(erint) > eri_env%eps_integral .AND. (irange(1) - 1 + iwa12 <= iwb12 .OR. isp1 /= isp2)) THEN
1680 icount2 = icount2 + 1
1681 eri(icount2) = erint
1682 eri_index(icount2) = iwb12
1683 END IF
1684 END IF
1685 END DO
1686 END DO
1687 stored_integrals = stored_integrals + icount2
1688 !
1689 isp = (isp1 - 1)*isp2 + (isp2 - isp1 + 1)
1690 CALL update_csr_matrix(eri_env%eri(isp)%csr_mat, icount2, eri, eri_index, iwa12)
1691 !
1692 DEALLOCATE (eri, eri_index)
1693 END DO
1694 ELSEIF (eri_env%method == eri_method_full_gpw) THEN
1695 DO isp2 = isp1, nspins
1696 CALL get_mo_set(mo_set=mos(isp2), nmo=nmo2)
1697 nx = (nmo2*(nmo2 + 1))/2
1698 ALLOCATE (eri(nx), eri_index(nx))
1699 icount2 = 0
1700 iwbs = 1
1701 IF (isp1 == isp2) iwbs = i1
1702 isp = (isp1 - 1)*isp2 + (isp2 - isp1 + 1)
1703 DO i3 = iwbs, SIZE(orbitals, 1)
1704 iwb1 = orbitals(i3, isp2)
1705 IF (eri_env%eri_gpw%store_wfn) THEN
1706 wfn3 => wfn_a(iwb1, isp2)
1707 ELSE
1708 CALL calculate_wavefunction(fm_mo_coeff_as(isp1), iwb1, wfn3, rho_g, atomic_kind_set, &
1709 qs_kind_set, cell, dft_control, particle_set, pw_env_sub)
1710 END IF
1711 CALL pw_zero(wfn_r)
1712 CALL pw_multiply(wfn_r, rho_r, wfn3)
1713 iwbt = i3
1714 IF (isp1 == isp2 .AND. i1 == i3) iwbt = i2
1715 DO i4 = iwbt, SIZE(orbitals, 1)
1716 iwb2 = orbitals(i4, isp2)
1717 IF (eri_env%eri_gpw%store_wfn) THEN
1718 wfn4 => wfn_a(iwb2, isp2)
1719 ELSE
1720 CALL calculate_wavefunction(fm_mo_coeff_as(isp1), iwb2, wfn4, rho_g, atomic_kind_set, &
1721 qs_kind_set, cell, dft_control, particle_set, pw_env_sub)
1722 END IF
1723 ! We reduce the amount of communication by collecting the local sums first and sum globally later
1724 erint = pw_integral_ab(wfn_r, wfn4, local_only=.true.)
1725 icount2 = icount2 + 1
1726 eri(icount2) = erint
1727 eri_index(icount2) = csr_idx_to_combined(iwb1, iwb2, nmo2)
1728 END DO
1729 END DO
1730 ! Now, we sum the integrals globally
1731 CALL eri_env%para_env_sub%sum(eri)
1732 ! and we reorder the integrals to prevent storing too small integrals
1733 intcount = 0
1734 icount2 = 0
1735 iwbs = 1
1736 IF (isp1 == isp2) iwbs = i1
1737 isp = (isp1 - 1)*isp2 + (isp2 - isp1 + 1)
1738 DO i3 = iwbs, SIZE(orbitals, 1)
1739 iwb1 = orbitals(i3, isp2)
1740 iwbt = i3
1741 IF (isp1 == isp2 .AND. i1 == i3) iwbt = i2
1742 DO i4 = iwbt, SIZE(orbitals, 1)
1743 iwb2 = orbitals(i4, isp2)
1744 intcount = intcount + 1
1745 erint = eri(intcount)
1746 IF (abs(erint) > eri_env%eps_integral) THEN
1747 IF (mod(intcount, eri_env%para_env_sub%num_pe) == eri_env%para_env_sub%mepos) THEN
1748 icount2 = icount2 + 1
1749 eri(icount2) = erint
1750 eri_index(icount2) = eri_index(intcount)
1751 END IF
1752 END IF
1753 END DO
1754 END DO
1755 stored_integrals = stored_integrals + icount2
1756 !
1757 CALL update_csr_matrix(eri_env%eri(isp)%csr_mat, icount2, eri, eri_index, iwa12)
1758 !
1759 DEALLOCATE (eri, eri_index)
1760 END DO
1761 ELSE
1762 cpabort("Unknown option")
1763 END IF
1764 END DO
1765 END DO
1766 END DO
1767
1768 IF (print1 .AND. iw > 0) THEN
1769 WRITE (iw, "(T2,'ERI_GPW|',' Number of Integrals stored ',T71,I10)") stored_integrals
1770 END IF
1771
1772 IF (eri_env%eri_gpw%store_wfn) THEN
1773 DO ispin = 1, nspins
1774 DO i1 = 1, SIZE(orbitals, 1)
1775 iwfn = orbitals(i1, ispin)
1776 CALL wfn_a(iwfn, ispin)%release()
1777 END DO
1778 END DO
1779 DEALLOCATE (wfn_a)
1780 ELSE
1781 CALL wfn1%release()
1782 CALL wfn2%release()
1783 DEALLOCATE (wfn1, wfn2)
1784 IF (eri_env%method /= eri_method_gpw_ht) THEN
1785 CALL wfn3%release()
1786 CALL wfn4%release()
1787 DEALLOCATE (wfn3, wfn4)
1788 END IF
1789 END IF
1790 CALL auxbas_pw_pool%give_back_pw(wfn_r)
1791 CALL auxbas_pw_pool%give_back_pw(rho_g)
1792 CALL auxbas_pw_pool%give_back_pw(rho_r)
1793 CALL auxbas_pw_pool%give_back_pw(pot_g)
1794
1795 IF (eri_env%method == eri_method_gpw_ht) THEN
1796 DO ispin = 1, nspins
1797 CALL dbcsr_release(mo_coeff_as(ispin))
1798 CALL dbcsr_release(matrix_pq_rnu(ispin))
1799 CALL cp_fm_release(fm_matrix_pq_rnu(ispin))
1800 CALL cp_fm_release(fm_matrix_pq_rs(ispin))
1801 END DO
1802 DEALLOCATE (matrix_pq_rnu, fm_matrix_pq_rnu, fm_matrix_pq_rs)
1803 CALL deallocate_task_list(task_list_sub)
1804 END IF
1805 DO ispin = 1, nspins
1806 CALL dbcsr_release(mo_coeff_as(ispin))
1807 CALL cp_fm_release(fm_mo_coeff_as(ispin))
1808 END DO
1809 DEALLOCATE (mo_coeff_as, fm_mo_coeff_as)
1810 CALL release_neighbor_list_sets(sab_orb_sub)
1811 CALL cp_blacs_env_release(blacs_env_sub)
1812 CALL dbcsr_release(mat_munu%matrix)
1813 DEALLOCATE (mat_munu%matrix)
1814 CALL pw_env_release(pw_env_sub)
1815 ! Return to the old qs_control
1816 dft_control%qs_control => qs_control_old
1817 DEALLOCATE (qs_control%e_cutoff)
1818 DEALLOCATE (qs_control)
1819
1820 ! print out progress
1821 IF (iw > 0) THEN
1822 t2 = m_walltime()
1823 WRITE (iw, '(/,T2,A,T66,F14.2)') "ERI_GPW| ERI calculation took (sec)", t2 - t1
1824 CALL m_flush(iw)
1825 END IF
1826
1827 CALL timestop(handle)
1828
1829 END SUBROUTINE calculate_eri_gpw
1830
1831! **************************************************************************************************
1832!> \brief Sets the Green's function for the ERI calculation. Here we deal with the G=0 case!
1833!> \param green ...
1834!> \param eri_env ...
1835!> \par History
1836!> 04.2016 created [JGH]
1837!> 08.2025 added support for the LR truncation [SB]
1838! **************************************************************************************************
1839 SUBROUTINE pw_eri_green_create(green, eri_env)
1840
1841 TYPE(greens_fn_type), INTENT(INOUT) :: green
1842 TYPE(eri_type) :: eri_env
1843
1844 COMPLEX(KIND=dp) :: erf_fac_p, z_p
1845 INTEGER :: ig
1846 REAL(kind=dp) :: cossin_fac, ea, erfcos_fac, exp_prefac, &
1847 g, g0, g2, g3d, ga, ginf, omega, &
1848 omega2, rc, rc2
1849
1850 ! initialize influence function
1851 associate(gf => green%influence_fn, grid => green%influence_fn%pw_grid)
1852 SELECT CASE (green%method)
1853 CASE (periodic3d)
1854
1855 SELECT CASE (eri_env%operator)
1856 CASE (eri_operator_coulomb)
1857 DO ig = grid%first_gne0, grid%ngpts_cut_local
1858 g2 = grid%gsq(ig)
1859 gf%array(ig) = fourpi/g2
1860 END DO
1861 IF (grid%have_g0) gf%array(1) = 0.0_dp
1862
1863 CASE (eri_operator_yukawa)
1864 CALL cp_warn(__location__, "Yukawa operator has not been tested")
1865 omega2 = eri_env%omega**2
1866 DO ig = grid%first_gne0, grid%ngpts_cut_local
1867 g2 = grid%gsq(ig)
1868 gf%array(ig) = fourpi/(omega2 + g2)
1869 END DO
1870 IF (grid%have_g0) gf%array(1) = fourpi/omega2
1871
1872 CASE (eri_operator_erf)
1873 omega2 = eri_env%omega**2
1874 DO ig = grid%first_gne0, grid%ngpts_cut_local
1875 g2 = grid%gsq(ig)
1876 gf%array(ig) = fourpi/g2*exp(-0.25_dp*g2/omega2)
1877 END DO
1878 IF (grid%have_g0) gf%array(1) = 0.0_dp
1879
1880 CASE (eri_operator_erfc)
1881 omega2 = eri_env%omega**2
1882 DO ig = grid%first_gne0, grid%ngpts_cut_local
1883 g2 = grid%gsq(ig)
1884 gf%array(ig) = fourpi/g2*(1.0_dp - exp(-0.25_dp*g2/omega2))
1885 END DO
1886 IF (grid%have_g0) gf%array(1) = pi/omega2
1887
1888 CASE (eri_operator_trunc)
1889 rc = eri_env%cutoff_radius
1890 DO ig = grid%first_gne0, grid%ngpts_cut_local
1891 g2 = grid%gsq(ig)
1892 g = sqrt(g2)
1893 ! Taylor expansion around zero
1894 IF (g*rc >= 0.005_dp) THEN
1895 gf%array(ig) = fourpi/g2*(1.0_dp - cos(g*rc))
1896 ELSE
1897 gf%array(ig) = fourpi/g2*(g*rc)**2/2.0_dp*(1.0_dp - (g*rc)**2/12.0_dp)
1898 END IF
1899 END DO
1900 IF (grid%have_g0) gf%array(1) = twopi*rc**2
1901
1902 CASE (eri_operator_lr_trunc)
1903 omega = eri_env%omega
1904 omega2 = omega**2
1905 rc = eri_env%cutoff_radius
1906 rc2 = rc**2
1907 g0 = 0.001_dp ! threshold for the G=0 case
1908 ginf = 20.0_dp ! threshold for the Taylor exapnsion arounf G=∞
1909 DO ig = grid%first_gne0, grid%ngpts_cut_local
1910 g2 = grid%gsq(ig)
1911 g = sqrt(g2)
1912 IF (g <= 2.0_dp*g0) THEN
1913 gf%array(ig) = -pi/omega2*erf(omega*rc) &
1914 + twopi*rc2*erf(omega*rc) &
1915 + 2*rootpi*rc*exp(-omega2*rc2)/omega
1916 ELSE IF (g >= 2.0_dp*ginf*omega) THEN
1917 ! exponential prefactor
1918 exp_prefac = exp(-omega2*rc2)/(rootpi*(omega2*rc2 + 0.25_dp*g2/omega2))
1919 ! cos sin factor
1920 cossin_fac = omega*rc*cos(g*rc) - 0.5_dp*g/omega*sin(g*rc)
1921 ! real erf term with cosine
1922 erfcos_fac = erf(omega*rc)*cos(g*rc)
1923 ! Combine terms
1924 gf%array(ig) = fourpi/g2*(-exp_prefac*cossin_fac - erfcos_fac)
1925 ELSE
1926 ! exponential prefactor
1927 exp_prefac = twopi/g2*exp(-0.25_dp*g2/omega2)
1928 ! Compute complex arguments for erf
1929 z_p = cmplx(omega*rc, 0.5_dp*g/omega, kind=dp)
1930 ! Evaluate complex error functions
1931 erf_fac_p = 2.0_dp*real(erfz_fast(z_p))
1932 ! Real erf term with cosine
1933 erfcos_fac = fourpi/g2*erf(omega*rc)*cos(g*rc)
1934 ! Combine terms
1935 gf%array(ig) = exp_prefac*erf_fac_p - erfcos_fac
1936 END IF
1937 END DO
1938 IF (grid%have_g0) THEN
1939 gf%array(1) = -pi/omega2*erf(omega*rc) &
1940 + twopi*rc2*erf(omega*rc) &
1941 + 2*rootpi*rc*exp(-omega2*rc2)/omega
1942 END IF
1943
1944 CASE DEFAULT
1945 cpabort("Please specify a valid operator for the periodic Poisson solver")
1946 END SELECT
1947
1948 ! The analytic Poisson solver simply limits the domain of integration
1949 ! of the Fourier transform to a sphere of radius Rc, rather than integrating
1950 ! over all space (-∞,∞)
1951 CASE (analytic0d)
1952
1953 SELECT CASE (eri_env%operator)
1954 ! This is identical to the truncated Coulomb operator integrated
1955 ! over all space, when the truncation radius is equal to the radius of
1956 ! the Poisson solver
1957 CASE (eri_operator_coulomb, eri_operator_trunc)
1958 IF (eri_env%operator == eri_operator_coulomb) THEN
1959 rc = green%radius
1960 ELSE
1961 rc = eri_env%cutoff_radius
1962 END IF
1963 DO ig = grid%first_gne0, grid%ngpts_cut_local
1964 g2 = grid%gsq(ig)
1965 g = sqrt(g2)
1966 ! Taylor expansion around zero
1967 IF (g*rc >= 0.005_dp) THEN
1968 gf%array(ig) = fourpi/g2*(1.0_dp - cos(g*rc))
1969 ELSE
1970 gf%array(ig) = fourpi/g2*(g*rc)**2/2.0_dp*(1.0_dp - (g*rc)**2/12.0_dp)
1971 END IF
1972 END DO
1973 IF (grid%have_g0) gf%array(1) = twopi*rc**2
1974
1975 ! Not tested
1976 CASE (eri_operator_yukawa)
1977 CALL cp_warn(__location__, "Yukawa operator has not been tested")
1978 rc = green%radius
1979 omega = eri_env%omega
1980 ea = exp(-omega*rc)
1981 DO ig = grid%first_gne0, grid%ngpts_cut_local
1982 g2 = grid%gsq(ig)
1983 g = sqrt(g2)
1984 g3d = fourpi/(omega**2 + g2)
1985 gf%array(ig) = g3d*(1.0_dp - ea*(cos(g*rc) + omega/g*sin(g*rc)))
1986 END DO
1987 IF (grid%have_g0) gf%array(1) = fourpi/(omega**2)*(1.0_dp - ea*(1.0_dp + omega*rc))
1988
1989 ! Long-range Coulomb
1990 ! TODO: this should be equivalent to LR truncated Coulomb from above!
1991 CASE (eri_operator_erf, eri_operator_lr_trunc)
1992 IF (eri_env%operator == eri_operator_erf) THEN
1993 rc = green%radius
1994 ELSE
1995 rc = eri_env%cutoff_radius
1996 END IF
1997 omega2 = eri_env%omega**2
1998 DO ig = grid%first_gne0, grid%ngpts_cut_local
1999 g2 = grid%gsq(ig)
2000 g = sqrt(g2)
2001 ga = -0.25_dp*g2/omega2
2002 gf%array(ig) = fourpi/g2*exp(ga)*(1.0_dp - cos(g*rc))
2003 END DO
2004 IF (grid%have_g0) gf%array(1) = twopi*rc**2
2005
2006 ! Short-range Coulomb
2007 ! TODO: this should actually be properly derived and see whether it is correct
2008 CASE (eri_operator_erfc)
2009 CALL cp_warn(__location__, &
2010 "Short-range Coulomb operator may be incorrect with ANALYTIC0D Poisson solver")
2011 rc = green%radius
2012 omega2 = eri_env%omega**2
2013 DO ig = grid%first_gne0, grid%ngpts_cut_local
2014 g2 = grid%gsq(ig)
2015 g = sqrt(g2)
2016 ga = -0.25_dp*g2/omega2
2017 gf%array(ig) = fourpi/g2*(1.0_dp - exp(ga))*(1.0_dp - cos(g*rc))
2018 END DO
2019 IF (grid%have_g0) gf%array(1) = pi/omega2
2020
2021 CASE DEFAULT
2022 cpabort("Unsupported operator")
2023 END SELECT
2024
2025 CASE DEFAULT
2026 cpabort("Unsupported Poisson solver")
2027 END SELECT
2028 END associate
2029
2030 END SUBROUTINE pw_eri_green_create
2031
2032! **************************************************************************************************
2033!> \brief Adds data for a new row to the csr matrix
2034!> \param csr_mat ...
2035!> \param nnz ...
2036!> \param rdat ...
2037!> \param rind ...
2038!> \param irow ...
2039!> \par History
2040!> 04.2016 created [JGH]
2041! **************************************************************************************************
2042 SUBROUTINE update_csr_matrix(csr_mat, nnz, rdat, rind, irow)
2043
2044 TYPE(dbcsr_csr_type), INTENT(INOUT) :: csr_mat
2045 INTEGER, INTENT(IN) :: nnz
2046 REAL(kind=dp), DIMENSION(:), INTENT(IN) :: rdat
2047 INTEGER, DIMENSION(:), INTENT(IN) :: rind
2048 INTEGER, INTENT(IN) :: irow
2049
2050 INTEGER :: k, nrow, nze, nze_new
2051
2052 IF (irow /= 0) THEN
2053 nze = csr_mat%nze_local
2054 nze_new = nze + nnz
2055 ! values
2056 CALL reallocate(csr_mat%nzval_local%r_dp, 1, nze_new)
2057 csr_mat%nzval_local%r_dp(nze + 1:nze_new) = rdat(1:nnz)
2058 ! col indices
2059 CALL reallocate(csr_mat%colind_local, 1, nze_new)
2060 csr_mat%colind_local(nze + 1:nze_new) = rind(1:nnz)
2061 ! rows
2062 nrow = csr_mat%nrows_local
2063 CALL reallocate(csr_mat%rowptr_local, 1, irow + 1)
2064 csr_mat%rowptr_local(nrow + 1:irow) = nze + 1
2065 csr_mat%rowptr_local(irow + 1) = nze_new + 1
2066 ! nzerow
2067 CALL reallocate(csr_mat%nzerow_local, 1, irow)
2068 DO k = nrow + 1, irow
2069 csr_mat%nzerow_local(k) = csr_mat%rowptr_local(k + 1) - csr_mat%rowptr_local(k)
2070 END DO
2071 csr_mat%nrows_local = irow
2072 csr_mat%nze_local = csr_mat%nze_local + nnz
2073 END IF
2074 csr_mat%nze_total = csr_mat%nze_total + nnz
2075 csr_mat%has_indices = .true.
2076
2077 END SUBROUTINE update_csr_matrix
2078
2079! **************************************************************************************************
2080!> \brief Computes and prints the active orbitals on Cube Files
2081!> \param input ...
2082!> \param qs_env the qs_env in which the qs_env lives
2083!> \param mos ...
2084! **************************************************************************************************
2085 SUBROUTINE print_orbital_cubes(input, qs_env, mos)
2086 TYPE(section_vals_type), POINTER :: input
2087 TYPE(qs_environment_type), POINTER :: qs_env
2088 TYPE(mo_set_type), DIMENSION(:), INTENT(IN) :: mos
2089
2090 CHARACTER(LEN=default_path_length) :: filebody, filename, title
2091 INTEGER :: i, imo, isp, nmo, str(3), unit_nr
2092 INTEGER, DIMENSION(:), POINTER :: alist, blist, istride
2093 LOGICAL :: do_mo, explicit_a, explicit_b
2094 TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
2095 TYPE(cell_type), POINTER :: cell
2096 TYPE(cp_fm_type), POINTER :: mo_coeff
2097 TYPE(dft_control_type), POINTER :: dft_control
2098 TYPE(mp_para_env_type), POINTER :: para_env
2099 TYPE(particle_list_type), POINTER :: particles
2100 TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
2101 TYPE(pw_c1d_gs_type) :: wf_g
2102 TYPE(pw_env_type), POINTER :: pw_env
2103 TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
2104 TYPE(pw_r3d_rs_type) :: wf_r
2105 TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
2106 TYPE(qs_subsys_type), POINTER :: subsys
2107 TYPE(section_vals_type), POINTER :: dft_section, scf_input
2108
2109 CALL section_vals_val_get(input, "FILENAME", c_val=filebody)
2110 CALL section_vals_val_get(input, "STRIDE", i_vals=istride)
2111 IF (SIZE(istride) == 1) THEN
2112 str(1:3) = istride(1)
2113 ELSEIF (SIZE(istride) == 3) THEN
2114 str(1:3) = istride(1:3)
2115 ELSE
2116 cpabort("STRIDE arguments inconsistent")
2117 END IF
2118 CALL section_vals_val_get(input, "ALIST", i_vals=alist, explicit=explicit_a)
2119 CALL section_vals_val_get(input, "BLIST", i_vals=blist, explicit=explicit_b)
2120
2121 CALL get_qs_env(qs_env=qs_env, &
2122 dft_control=dft_control, &
2123 para_env=para_env, &
2124 subsys=subsys, &
2125 atomic_kind_set=atomic_kind_set, &
2126 qs_kind_set=qs_kind_set, &
2127 cell=cell, &
2128 particle_set=particle_set, &
2129 pw_env=pw_env, &
2130 input=scf_input)
2131
2132 CALL qs_subsys_get(subsys, particles=particles)
2133 !
2134 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
2135 CALL auxbas_pw_pool%create_pw(wf_r)
2136 CALL auxbas_pw_pool%create_pw(wf_g)
2137 !
2138 dft_section => section_vals_get_subs_vals(scf_input, "DFT")
2139 !
2140 DO isp = 1, SIZE(mos)
2141 CALL get_mo_set(mo_set=mos(isp), mo_coeff=mo_coeff, nmo=nmo)
2142
2143 IF (SIZE(mos) > 1) THEN
2144 SELECT CASE (isp)
2145 CASE (1)
2146 CALL write_mo_set_to_output_unit(mos(isp), qs_kind_set, particle_set, &
2147 dft_section, 4, 0, final_mos=.true., spin="ALPHA")
2148 CASE (2)
2149 CALL write_mo_set_to_output_unit(mos(isp), qs_kind_set, particle_set, &
2150 dft_section, 4, 0, final_mos=.true., spin="BETA")
2151 CASE DEFAULT
2152 cpabort("Invalid spin")
2153 END SELECT
2154 ELSE
2155 CALL write_mo_set_to_output_unit(mos(isp), qs_kind_set, particle_set, &
2156 dft_section, 4, 0, final_mos=.true.)
2157 END IF
2158
2159 DO imo = 1, nmo
2160 IF (isp == 1 .AND. explicit_a) THEN
2161 IF (alist(1) == -1) THEN
2162 do_mo = .true.
2163 ELSE
2164 do_mo = .false.
2165 DO i = 1, SIZE(alist)
2166 IF (imo == alist(i)) do_mo = .true.
2167 END DO
2168 END IF
2169 ELSE IF (isp == 2 .AND. explicit_b) THEN
2170 IF (blist(1) == -1) THEN
2171 do_mo = .true.
2172 ELSE
2173 do_mo = .false.
2174 DO i = 1, SIZE(blist)
2175 IF (imo == blist(i)) do_mo = .true.
2176 END DO
2177 END IF
2178 ELSE
2179 do_mo = .true.
2180 END IF
2181 IF (.NOT. do_mo) cycle
2182 CALL calculate_wavefunction(mo_coeff, imo, wf_r, wf_g, atomic_kind_set, &
2183 qs_kind_set, cell, dft_control, particle_set, pw_env)
2184 IF (para_env%is_source()) THEN
2185 WRITE (filename, '(A,A1,I4.4,A1,I1.1,A)') trim(filebody), "_", imo, "_", isp, ".cube"
2186 CALL open_file(filename, unit_number=unit_nr, file_status="UNKNOWN", file_action="WRITE")
2187 WRITE (title, *) "Active Orbital ", imo, " spin ", isp
2188 ELSE
2189 unit_nr = -1
2190 END IF
2191 CALL cp_pw_to_cube(wf_r, unit_nr, title, particles=particles, stride=istride)
2192 IF (para_env%is_source()) THEN
2193 CALL close_file(unit_nr)
2194 END IF
2195 END DO
2196 END DO
2197
2198 CALL auxbas_pw_pool%give_back_pw(wf_r)
2199 CALL auxbas_pw_pool%give_back_pw(wf_g)
2200
2201 END SUBROUTINE print_orbital_cubes
2202
2203! **************************************************************************************************
2204!> \brief Writes a FCIDUMP file
2205!> \param active_space_env ...
2206!> \param as_input ...
2207!> \par History
2208!> 04.2016 created [JGH]
2209! **************************************************************************************************
2210 SUBROUTINE fcidump(active_space_env, as_input)
2211
2212 TYPE(active_space_type), POINTER :: active_space_env
2213 TYPE(section_vals_type), POINTER :: as_input
2214
2215 INTEGER :: i, i1, i2, i3, i4, isym, iw, m1, m2, &
2216 nmo, norb, nspins
2217 REAL(kind=dp) :: checksum, esub
2218 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: fmat
2219 TYPE(cp_logger_type), POINTER :: logger
2220 TYPE(eri_fcidump_checksum) :: eri_checksum
2221
2222 checksum = 0.0_dp
2223
2224 logger => cp_get_default_logger()
2225 iw = cp_print_key_unit_nr(logger, as_input, "FCIDUMP", &
2226 extension=".fcidump", file_status="REPLACE", file_action="WRITE", file_form="FORMATTED")
2227 !
2228 nspins = active_space_env%nspins
2229 norb = SIZE(active_space_env%active_orbitals, 1)
2230 IF (nspins == 1) THEN
2231 associate(ms2 => active_space_env%multiplicity, &
2232 nelec => active_space_env%nelec_active)
2233
2234 IF (iw > 0) THEN
2235 WRITE (iw, "(A,A,I4,A,I4,A,I2,A)") "&FCI", " NORB=", norb, ",NELEC=", nelec, ",MS2=", ms2, ","
2236 isym = 1
2237 WRITE (iw, "(A,1000(I1,','))") " ORBSYM=", (isym, i=1, norb)
2238 isym = 0
2239 WRITE (iw, "(A,I1,A)") " ISYM=", isym, ","
2240 WRITE (iw, "(A)") " /"
2241 END IF
2242 !
2243 ! Print integrals: ERI
2244 CALL active_space_env%eri%eri_foreach(1, active_space_env%active_orbitals, &
2245 eri_fcidump_print(iw, 1, 1), 1, 1)
2246 CALL eri_checksum%set(1, 1)
2247 CALL active_space_env%eri%eri_foreach(1, active_space_env%active_orbitals, eri_checksum, 1, 1)
2248
2249 ! Print integrals: Fij
2250 ! replicate Fock matrix
2251 nmo = active_space_env%eri%norb
2252 ALLOCATE (fmat(nmo, nmo))
2253 CALL replicate_and_symmetrize_matrix(nmo, active_space_env%fock_sub(1), fmat)
2254 IF (iw > 0) THEN
2255 i3 = 0; i4 = 0
2256 DO m1 = 1, SIZE(active_space_env%active_orbitals, 1)
2257 i1 = active_space_env%active_orbitals(m1, 1)
2258 DO m2 = m1, SIZE(active_space_env%active_orbitals, 1)
2259 i2 = active_space_env%active_orbitals(m2, 1)
2260 checksum = checksum + abs(fmat(i1, i2))
2261 WRITE (iw, "(ES23.16,4I4)") fmat(i1, i2), m1, m2, i3, i4
2262 END DO
2263 END DO
2264 END IF
2265 DEALLOCATE (fmat)
2266 ! Print energy
2267 esub = active_space_env%energy_inactive
2268 i1 = 0; i2 = 0; i3 = 0; i4 = 0
2269 checksum = checksum + abs(esub)
2270 IF (iw > 0) WRITE (iw, "(ES23.16,4I4)") esub, i1, i2, i3, i4
2271 END associate
2272
2273 ELSE
2274 associate(ms2 => active_space_env%multiplicity, &
2275 nelec => active_space_env%nelec_active)
2276
2277 IF (iw > 0) THEN
2278 WRITE (iw, "(A,A,I4,A,I4,A,I2,A)") "&FCI", " NORB=", norb, ",NELEC=", nelec, ",MS2=", ms2, ","
2279 isym = 1
2280 WRITE (iw, "(A,1000(I1,','))") " ORBSYM=", (isym, i=1, norb)
2281 isym = 0
2282 WRITE (iw, "(A,I1,A)") " ISYM=", isym, ","
2283 WRITE (iw, "(A,I1,A)") " UHF=", 1, ","
2284 WRITE (iw, "(A)") " /"
2285 END IF
2286 !
2287 ! Print integrals: ERI
2288 ! alpha-alpha
2289 CALL active_space_env%eri%eri_foreach(1, active_space_env%active_orbitals, &
2290 eri_fcidump_print(iw, 1, 1), 1, 1)
2291 CALL eri_checksum%set(1, 1)
2292 CALL active_space_env%eri%eri_foreach(1, active_space_env%active_orbitals, eri_checksum, 1, 1)
2293 ! alpha-beta
2294 CALL active_space_env%eri%eri_foreach(2, active_space_env%active_orbitals, &
2295 eri_fcidump_print(iw, 1, norb + 1), 1, 2)
2296 CALL eri_checksum%set(1, norb + 1)
2297 CALL active_space_env%eri%eri_foreach(2, active_space_env%active_orbitals, eri_checksum, 1, 2)
2298 ! beta-beta
2299 CALL active_space_env%eri%eri_foreach(3, active_space_env%active_orbitals, &
2300 eri_fcidump_print(iw, norb + 1, norb + 1), 2, 2)
2301 CALL eri_checksum%set(norb + 1, norb + 1)
2302 CALL active_space_env%eri%eri_foreach(3, active_space_env%active_orbitals, eri_checksum, 2, 2)
2303 ! Print integrals: Fij
2304 ! alpha
2305 nmo = active_space_env%eri%norb
2306 ALLOCATE (fmat(nmo, nmo))
2307 CALL replicate_and_symmetrize_matrix(nmo, active_space_env%fock_sub(1), fmat)
2308 IF (iw > 0) THEN
2309 i3 = 0; i4 = 0
2310 DO m1 = 1, norb
2311 i1 = active_space_env%active_orbitals(m1, 1)
2312 DO m2 = m1, norb
2313 i2 = active_space_env%active_orbitals(m2, 1)
2314 checksum = checksum + abs(fmat(i1, i2))
2315 WRITE (iw, "(ES23.16,4I4)") fmat(i1, i2), m1, m2, i3, i4
2316 END DO
2317 END DO
2318 END IF
2319 DEALLOCATE (fmat)
2320 ! beta
2321 ALLOCATE (fmat(nmo, nmo))
2322 CALL replicate_and_symmetrize_matrix(nmo, active_space_env%fock_sub(2), fmat)
2323 IF (iw > 0) THEN
2324 i3 = 0; i4 = 0
2325 DO m1 = 1, SIZE(active_space_env%active_orbitals, 1)
2326 i1 = active_space_env%active_orbitals(m1, 2)
2327 DO m2 = m1, SIZE(active_space_env%active_orbitals, 1)
2328 i2 = active_space_env%active_orbitals(m2, 2)
2329 checksum = checksum + abs(fmat(i1, i2))
2330 WRITE (iw, "(ES23.16,4I4)") fmat(i1, i2), m1 + norb, m2 + norb, i3, i4
2331 END DO
2332 END DO
2333 END IF
2334 DEALLOCATE (fmat)
2335 ! Print energy
2336 esub = active_space_env%energy_inactive
2337 i1 = 0; i2 = 0; i3 = 0; i4 = 0
2338 checksum = checksum + abs(esub)
2339 IF (iw > 0) WRITE (iw, "(ES23.16,4I4)") esub, i1, i2, i3, i4
2340 END associate
2341 END IF
2342 !
2343 CALL cp_print_key_finished_output(iw, logger, as_input, "FCIDUMP")
2344
2345 !>>
2346 iw = cp_logger_get_default_io_unit(logger)
2347 IF (iw > 0) WRITE (iw, '(T4,A,T66,F12.8)') "FCIDUMP| Checksum:", eri_checksum%checksum + checksum
2348 !<<
2349
2350 END SUBROUTINE fcidump
2351
2352! **************************************************************************************************
2353!> \brief replicate and symmetrize a matrix
2354!> \param norb the number of orbitals
2355!> \param distributed_matrix ...
2356!> \param replicated_matrix ...
2357! **************************************************************************************************
2358 SUBROUTINE replicate_and_symmetrize_matrix(norb, distributed_matrix, replicated_matrix)
2359 INTEGER, INTENT(IN) :: norb
2360 TYPE(cp_fm_type), INTENT(IN) :: distributed_matrix
2361 REAL(dp), DIMENSION(:, :), INTENT(INOUT) :: replicated_matrix
2362
2363 INTEGER :: i1, i2
2364 REAL(dp) :: mval
2365
2366 replicated_matrix(:, :) = 0.0_dp
2367 DO i1 = 1, norb
2368 DO i2 = i1, norb
2369 CALL cp_fm_get_element(distributed_matrix, i1, i2, mval)
2370 replicated_matrix(i1, i2) = mval
2371 replicated_matrix(i2, i1) = mval
2372 END DO
2373 END DO
2374 END SUBROUTINE replicate_and_symmetrize_matrix
2375
2376! **************************************************************************************************
2377!> \brief Calculates active space Fock matrix and inactive energy
2378!> \param active_space_env ...
2379!> \par History
2380!> 06.2016 created [JGH]
2381! **************************************************************************************************
2382 SUBROUTINE subspace_fock_matrix(active_space_env)
2383
2384 TYPE(active_space_type), POINTER :: active_space_env
2385
2386 INTEGER :: i1, i2, is, norb, nspins
2387 REAL(kind=dp) :: eeri, eref, esub, mval
2388 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: ks_a_mat, ks_a_ref, ks_b_mat, ks_b_ref, &
2389 ks_mat, ks_ref, p_a_mat, p_b_mat, p_mat
2390 TYPE(cp_fm_type), POINTER :: matrix, mo_coef
2391 TYPE(dbcsr_csr_type), POINTER :: eri, eri_aa, eri_ab, eri_bb
2392
2393 eref = active_space_env%energy_ref
2394 nspins = active_space_env%nspins
2395
2396 IF (nspins == 1) THEN
2397 CALL get_mo_set(active_space_env%mos_active(1), nmo=norb, mo_coeff=mo_coef)
2398 !
2399 ! Loop over ERI, calculate subspace HF energy and Fock matrix
2400 !
2401 ! replicate KS, Core, and P matrices
2402 ALLOCATE (ks_mat(norb, norb), ks_ref(norb, norb), p_mat(norb, norb))
2403 ks_ref = 0.0_dp
2404
2405 ! ks_mat contains the KS/Fock matrix (of full density) projected onto the AS MO subspace (f_ref in eq. 19)
2406 CALL replicate_and_symmetrize_matrix(norb, active_space_env%ks_sub(1), ks_mat)
2407 CALL replicate_and_symmetrize_matrix(norb, active_space_env%p_active(1), p_mat)
2408
2409 ! compute ks_ref = V_H[rho^A] + V_HFX[rho^A]
2410 eri => active_space_env%eri%eri(1)%csr_mat
2411 CALL build_subspace_fock_matrix(active_space_env%active_orbitals, eri, p_mat, ks_ref, &
2412 active_space_env%eri%comm_exchange)
2413
2414 ! compute eeri = E_H[rho^A] + E_HFX[rho^A] as
2415 ! eeri = 1/2 * (SUM_pq (V_H[rho^A] + V_HFX[rho^A])_pq * D^A_pq)
2416 eeri = 0.5_dp*sum(ks_ref*p_mat)
2417
2418 ! now calculate the inactive energy acoording to eq. 19, that is
2419 ! esub = E^I = E_ref - f_ref .* D^A + E_H[rho^A] + E_HFX[rho^A]
2420 ! where f^ref = ks_mat, which is the KS/Fock matrix in MO basis, transformed previously
2421 ! and is equal to ks_mat = h^0 + V_core + V_H[rho] + V_HFX[rho]
2422 esub = eref - sum(ks_mat(1:norb, 1:norb)*p_mat(1:norb, 1:norb)) + eeri
2423
2424 ! reuse ks_mat to store f^I = f^ref - (V_H[rho^A] + V_HFX[rho^A]) according to eq. 20
2425 ks_mat(1:norb, 1:norb) = ks_mat(1:norb, 1:norb) - ks_ref(1:norb, 1:norb)
2426 ! this is now the embedding potential for the AS calculation!
2427
2428 active_space_env%energy_inactive = esub
2429
2430 CALL cp_fm_release(active_space_env%fock_sub)
2431 ALLOCATE (active_space_env%fock_sub(nspins))
2432 DO is = 1, nspins
2433 matrix => active_space_env%ks_sub(is)
2434 CALL cp_fm_create(active_space_env%fock_sub(is), matrix%matrix_struct, &
2435 name="Active Fock operator")
2436 END DO
2437 matrix => active_space_env%fock_sub(1)
2438 DO i1 = 1, norb
2439 DO i2 = 1, norb
2440 mval = ks_mat(i1, i2)
2441 CALL cp_fm_set_element(matrix, i1, i2, mval)
2442 END DO
2443 END DO
2444 ELSE
2445
2446 CALL get_mo_set(active_space_env%mos_active(1), nmo=norb)
2447 !
2448 ! Loop over ERI, calculate subspace HF energy and Fock matrix
2449 !
2450 ! replicate KS, Core, and P matrices
2451 ALLOCATE (ks_a_mat(norb, norb), ks_b_mat(norb, norb), &
2452 & ks_a_ref(norb, norb), ks_b_ref(norb, norb), &
2453 & p_a_mat(norb, norb), p_b_mat(norb, norb))
2454 ks_a_ref(:, :) = 0.0_dp; ks_b_ref(:, :) = 0.0_dp
2455
2456 CALL replicate_and_symmetrize_matrix(norb, active_space_env%p_active(1), p_a_mat)
2457 CALL replicate_and_symmetrize_matrix(norb, active_space_env%p_active(2), p_b_mat)
2458 CALL replicate_and_symmetrize_matrix(norb, active_space_env%ks_sub(1), ks_a_mat)
2459 CALL replicate_and_symmetrize_matrix(norb, active_space_env%ks_sub(2), ks_b_mat)
2460 !
2461 !
2462 eri_aa => active_space_env%eri%eri(1)%csr_mat
2463 eri_ab => active_space_env%eri%eri(2)%csr_mat
2464 eri_bb => active_space_env%eri%eri(3)%csr_mat
2465 CALL build_subspace_spin_fock_matrix(active_space_env%active_orbitals, eri_aa, eri_ab, p_a_mat, p_b_mat, ks_a_ref, &
2466 tr_mixed_eri=.false., comm_exchange=active_space_env%eri%comm_exchange)
2467 CALL build_subspace_spin_fock_matrix(active_space_env%active_orbitals, eri_bb, eri_ab, p_b_mat, p_a_mat, ks_b_ref, &
2468 tr_mixed_eri=.true., comm_exchange=active_space_env%eri%comm_exchange)
2469 !
2470 ! calculate energy
2471 eeri = 0.0_dp
2472 eeri = 0.5_dp*(sum(ks_a_ref*p_a_mat) + sum(ks_b_ref*p_b_mat))
2473 esub = eref - sum(ks_a_mat*p_a_mat) - sum(ks_b_mat*p_b_mat) + eeri
2474 ks_a_mat(:, :) = ks_a_mat(:, :) - ks_a_ref(:, :)
2475 ks_b_mat(:, :) = ks_b_mat(:, :) - ks_b_ref(:, :)
2476 !
2477 active_space_env%energy_inactive = esub
2478 !
2479 CALL cp_fm_release(active_space_env%fock_sub)
2480 ALLOCATE (active_space_env%fock_sub(nspins))
2481 DO is = 1, nspins
2482 matrix => active_space_env%ks_sub(is)
2483 CALL cp_fm_create(active_space_env%fock_sub(is), matrix%matrix_struct, &
2484 name="Active Fock operator")
2485 END DO
2486
2487 matrix => active_space_env%fock_sub(1)
2488 DO i1 = 1, norb
2489 DO i2 = 1, norb
2490 mval = ks_a_mat(i1, i2)
2491 CALL cp_fm_set_element(matrix, i1, i2, mval)
2492 END DO
2493 END DO
2494 matrix => active_space_env%fock_sub(2)
2495 DO i1 = 1, norb
2496 DO i2 = 1, norb
2497 mval = ks_b_mat(i1, i2)
2498 CALL cp_fm_set_element(matrix, i1, i2, mval)
2499 END DO
2500 END DO
2501
2502 END IF
2503
2504 END SUBROUTINE subspace_fock_matrix
2505
2506! **************************************************************************************************
2507!> \brief build subspace fockian
2508!> \param active_orbitals the active orbital indices
2509!> \param eri two electon integrals in MO
2510!> \param p_mat density matrix
2511!> \param ks_ref fockian matrix
2512!> \param comm_exchange ...
2513! **************************************************************************************************
2514 SUBROUTINE build_subspace_fock_matrix(active_orbitals, eri, p_mat, ks_ref, comm_exchange)
2515 INTEGER, DIMENSION(:, :), INTENT(IN) :: active_orbitals
2516 TYPE(dbcsr_csr_type), INTENT(IN) :: eri
2517 REAL(dp), DIMENSION(:, :), INTENT(IN) :: p_mat
2518 REAL(dp), DIMENSION(:, :), INTENT(INOUT) :: ks_ref
2519 TYPE(mp_comm_type), INTENT(IN) :: comm_exchange
2520
2521 CHARACTER(LEN=*), PARAMETER :: routinen = 'build_subspace_fock_matrix'
2522
2523 INTEGER :: handle, i1, i12, i12l, i2, i3, i34, &
2524 i34l, i4, irptr, m1, m2, nindex, &
2525 nmo_total, norb
2526 INTEGER, DIMENSION(2) :: irange
2527 REAL(dp) :: erint
2528 TYPE(mp_comm_type) :: mp_group
2529
2530 CALL timeset(routinen, handle)
2531
2532 ! Nothing to do
2533 norb = SIZE(active_orbitals, 1)
2534 nmo_total = SIZE(p_mat, 1)
2535 nindex = (nmo_total*(nmo_total + 1))/2
2536 CALL mp_group%set_handle(eri%mp_group%get_handle())
2537 irange = get_irange_csr(nindex, comm_exchange)
2538 DO m1 = 1, norb
2539 i1 = active_orbitals(m1, 1)
2540 DO m2 = m1, norb
2541 i2 = active_orbitals(m2, 1)
2542 i12 = csr_idx_to_combined(i1, i2, nmo_total)
2543 IF (i12 >= irange(1) .AND. i12 <= irange(2)) THEN
2544 i12l = i12 - irange(1) + 1
2545 irptr = eri%rowptr_local(i12l) - 1
2546 DO i34l = 1, eri%nzerow_local(i12l)
2547 i34 = eri%colind_local(irptr + i34l)
2548 CALL csr_idx_from_combined(i34, nmo_total, i3, i4)
2549 erint = eri%nzval_local%r_dp(irptr + i34l)
2550 ! Coulomb
2551 ks_ref(i1, i2) = ks_ref(i1, i2) + erint*p_mat(i3, i4)
2552 IF (i3 /= i4) THEN
2553 ks_ref(i1, i2) = ks_ref(i1, i2) + erint*p_mat(i3, i4)
2554 END IF
2555 IF (i12 /= i34) THEN
2556 ks_ref(i3, i4) = ks_ref(i3, i4) + erint*p_mat(i1, i2)
2557 IF (i1 /= i2) THEN
2558 ks_ref(i3, i4) = ks_ref(i3, i4) + erint*p_mat(i1, i2)
2559 END IF
2560 END IF
2561 ! Exchange
2562 erint = -0.5_dp*erint
2563 ks_ref(i1, i3) = ks_ref(i1, i3) + erint*p_mat(i2, i4)
2564 IF (i1 /= i2) THEN
2565 ks_ref(i2, i3) = ks_ref(i2, i3) + erint*p_mat(i1, i4)
2566 END IF
2567 IF (i3 /= i4) THEN
2568 ks_ref(i1, i4) = ks_ref(i1, i4) + erint*p_mat(i2, i3)
2569 END IF
2570 IF (i1 /= i2 .AND. i3 /= i4) THEN
2571 ks_ref(i2, i4) = ks_ref(i2, i4) + erint*p_mat(i1, i3)
2572 END IF
2573 END DO
2574 END IF
2575 END DO
2576 END DO
2577 !
2578 DO m1 = 1, norb
2579 i1 = active_orbitals(m1, 1)
2580 DO m2 = m1, norb
2581 i2 = active_orbitals(m2, 1)
2582 ks_ref(i2, i1) = ks_ref(i1, i2)
2583 END DO
2584 END DO
2585 CALL mp_group%sum(ks_ref)
2586
2587 CALL timestop(handle)
2588
2589 END SUBROUTINE build_subspace_fock_matrix
2590
2591! **************************************************************************************************
2592!> \brief build subspace fockian for unrestricted spins
2593!> \param active_orbitals the active orbital indices
2594!> \param eri_aa two electon integrals in MO with parallel spins
2595!> \param eri_ab two electon integrals in MO with anti-parallel spins
2596!> \param p_a_mat density matrix for up-spin
2597!> \param p_b_mat density matrix for down-spin
2598!> \param ks_a_ref fockian matrix for up-spin
2599!> \param tr_mixed_eri boolean to indicate Coulomb interaction alignment
2600!> \param comm_exchange ...
2601! **************************************************************************************************
2602 SUBROUTINE build_subspace_spin_fock_matrix(active_orbitals, eri_aa, eri_ab, p_a_mat, p_b_mat, ks_a_ref, tr_mixed_eri, &
2603 comm_exchange)
2604 INTEGER, DIMENSION(:, :), INTENT(IN) :: active_orbitals
2605 TYPE(dbcsr_csr_type), INTENT(IN) :: eri_aa, eri_ab
2606 REAL(dp), DIMENSION(:, :), INTENT(IN) :: p_a_mat, p_b_mat
2607 REAL(dp), DIMENSION(:, :), INTENT(INOUT) :: ks_a_ref
2608 LOGICAL, INTENT(IN) :: tr_mixed_eri
2609 TYPE(mp_comm_type), INTENT(IN) :: comm_exchange
2610
2611 CHARACTER(LEN=*), PARAMETER :: routinen = 'build_subspace_spin_fock_matrix'
2612
2613 INTEGER :: handle, i1, i12, i12l, i2, i3, i34, &
2614 i34l, i4, irptr, m1, m2, nindex, &
2615 nmo_total, norb, spin1, spin2
2616 INTEGER, DIMENSION(2) :: irange
2617 REAL(dp) :: erint
2618 TYPE(mp_comm_type) :: mp_group
2619
2620 CALL timeset(routinen, handle)
2621
2622 norb = SIZE(active_orbitals, 1)
2623 nmo_total = SIZE(p_a_mat, 1)
2624 nindex = (nmo_total*(nmo_total + 1))/2
2625 irange = get_irange_csr(nindex, comm_exchange)
2626 IF (tr_mixed_eri) THEN
2627 spin1 = 2
2628 spin2 = 1
2629 ELSE
2630 spin1 = 1
2631 spin2 = 2
2632 END IF
2633 DO m1 = 1, norb
2634 i1 = active_orbitals(m1, spin1)
2635 DO m2 = m1, norb
2636 i2 = active_orbitals(m2, spin1)
2637 i12 = csr_idx_to_combined(i1, i2, nmo_total)
2638 IF (i12 >= irange(1) .AND. i12 <= irange(2)) THEN
2639 i12l = i12 - irange(1) + 1
2640 irptr = eri_aa%rowptr_local(i12l) - 1
2641 DO i34l = 1, eri_aa%nzerow_local(i12l)
2642 i34 = eri_aa%colind_local(irptr + i34l)
2643 CALL csr_idx_from_combined(i34, nmo_total, i3, i4)
2644 erint = eri_aa%nzval_local%r_dp(irptr + i34l)
2645 ! Coulomb
2646 !F_ij += (ij|kl)*d_kl
2647 ks_a_ref(i1, i2) = ks_a_ref(i1, i2) + erint*p_a_mat(i3, i4)
2648 IF (i12 /= i34) THEN
2649 !F_kl += (ij|kl)*d_ij
2650 ks_a_ref(i3, i4) = ks_a_ref(i3, i4) + erint*p_a_mat(i1, i2)
2651 END IF
2652 ! Exchange
2653 erint = -1.0_dp*erint
2654 !F_ik -= (ij|kl)*d_jl
2655 ks_a_ref(i1, i3) = ks_a_ref(i1, i3) + erint*p_a_mat(i2, i4)
2656 IF (i1 /= i2) THEN
2657 !F_jk -= (ij|kl)*d_il
2658 ks_a_ref(i2, i3) = ks_a_ref(i2, i3) + erint*p_a_mat(i1, i4)
2659 END IF
2660 IF (i3 /= i4) THEN
2661 !F_il -= (ij|kl)*d_jk
2662 ks_a_ref(i1, i4) = ks_a_ref(i1, i4) + erint*p_a_mat(i2, i3)
2663 END IF
2664 IF (i1 /= i2 .AND. i3 /= i4) THEN
2665 !F_jl -= (ij|kl)*d_ik
2666 ks_a_ref(i2, i4) = ks_a_ref(i2, i4) + erint*p_a_mat(i1, i3)
2667 END IF
2668 END DO
2669 END IF
2670 END DO
2671 END DO
2672 !
2673
2674 irange = get_irange_csr(nindex, comm_exchange)
2675 DO m1 = 1, norb
2676 i1 = active_orbitals(m1, 1)
2677 DO m2 = m1, norb
2678 i2 = active_orbitals(m2, 1)
2679 i12 = csr_idx_to_combined(i1, i2, nmo_total)
2680 IF (i12 >= irange(1) .AND. i12 <= irange(2)) THEN
2681 i12l = i12 - irange(1) + 1
2682 irptr = eri_ab%rowptr_local(i12l) - 1
2683 DO i34l = 1, eri_ab%nzerow_local(i12l)
2684 i34 = eri_ab%colind_local(irptr + i34l)
2685 CALL csr_idx_from_combined(i34, nmo_total, i3, i4)
2686 erint = eri_ab%nzval_local%r_dp(irptr + i34l)
2687 ! Coulomb
2688 IF (tr_mixed_eri) THEN
2689 !F_kl += (kl beta|ij alpha )*d_alpha_ij
2690 ks_a_ref(i3, i4) = ks_a_ref(i3, i4) + erint*p_b_mat(i1, i2)
2691 ELSE
2692 !F_ij += (ij alpha|kl beta )*d_beta_kl
2693 ks_a_ref(i1, i2) = ks_a_ref(i1, i2) + erint*p_b_mat(i3, i4)
2694 END IF
2695 END DO
2696 END IF
2697 END DO
2698 END DO
2699 !
2700 DO m1 = 1, norb
2701 i1 = active_orbitals(m1, spin1)
2702 DO m2 = m1, norb
2703 i2 = active_orbitals(m2, spin1)
2704 ks_a_ref(i2, i1) = ks_a_ref(i1, i2)
2705 END DO
2706 END DO
2707 CALL mp_group%set_handle(eri_aa%mp_group%get_handle())
2708 CALL mp_group%sum(ks_a_ref)
2709
2710 CALL timestop(handle)
2711
2712 END SUBROUTINE build_subspace_spin_fock_matrix
2713
2714! **************************************************************************************************
2715!> \brief Creates a local basis
2716!> \param pro_basis_set ...
2717!> \param zval ...
2718!> \param ishell ...
2719!> \param nshell ...
2720!> \param lnam ...
2721!> \par History
2722!> 05.2016 created [JGH]
2723! **************************************************************************************************
2724 SUBROUTINE create_pro_basis(pro_basis_set, zval, ishell, nshell, lnam)
2725 TYPE(gto_basis_set_type), POINTER :: pro_basis_set
2726 INTEGER, INTENT(IN) :: zval, ishell
2727 INTEGER, DIMENSION(:), INTENT(IN) :: nshell
2728 CHARACTER(len=*), DIMENSION(:), INTENT(IN) :: lnam
2729
2730 CHARACTER(len=6), DIMENSION(:), POINTER :: sym
2731 INTEGER :: i, l, nj
2732 INTEGER, DIMENSION(4, 7) :: ne
2733 INTEGER, DIMENSION(:), POINTER :: lq, nq
2734 REAL(kind=dp), DIMENSION(:), POINTER :: zet
2735 TYPE(sto_basis_set_type), POINTER :: sto_basis_set
2736
2737 cpassert(.NOT. ASSOCIATED(pro_basis_set))
2738 NULLIFY (sto_basis_set)
2739
2740 ! electronic configuration
2741 ne = 0
2742 DO l = 1, 4 !lq(1)+1
2743 nj = 2*(l - 1) + 1
2744 DO i = l, 7 ! nq(1)
2745 ne(l, i) = ptable(zval)%e_conv(l - 1) - 2*nj*(i - l)
2746 ne(l, i) = max(ne(l, i), 0)
2747 ne(l, i) = min(ne(l, i), 2*nj)
2748 END DO
2749 END DO
2750 ALLOCATE (nq(ishell), lq(ishell), zet(ishell), sym(ishell))
2751 DO i = 1, ishell
2752 nq(i) = nshell(i)
2753 SELECT CASE (lnam(i))
2754 CASE ('S', 's')
2755 lq(i) = 0
2756 CASE ('P', 'p')
2757 lq(i) = 1
2758 CASE ('D', 'd')
2759 lq(i) = 2
2760 CASE ('F', 'f')
2761 lq(i) = 3
2762 CASE DEFAULT
2763 cpabort("Wrong l QN")
2764 END SELECT
2765 sym(i) = lnam(i)
2766 zet(i) = srules(zval, ne, nq(1), lq(1))
2767 END DO
2768 CALL allocate_sto_basis_set(sto_basis_set)
2769 CALL set_sto_basis_set(sto_basis_set, nshell=1, nq=nq, lq=lq, zet=zet, symbol=sym)
2770 CALL create_gto_from_sto_basis(sto_basis_set, pro_basis_set, 6)
2771 pro_basis_set%norm_type = 2
2772 CALL init_orb_basis_set(pro_basis_set)
2773 CALL deallocate_sto_basis_set(sto_basis_set)
2774
2775 END SUBROUTINE create_pro_basis
2776
2777! **************************************************************************************************
2778!> \brief Update the density matrix in AO basis with the active density contribution
2779!> \param active_space_env the active space environment
2780!> \param rho_ao the density matrix in AO basis
2781! **************************************************************************************************
2782 SUBROUTINE update_density_ao(active_space_env, rho_ao)
2783 TYPE(active_space_type), POINTER :: active_space_env
2784 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: rho_ao
2785
2786 INTEGER :: ispin, nao, nmo, nspins
2787 TYPE(cp_fm_type) :: r, u
2788 TYPE(cp_fm_type), POINTER :: c_active, p_active_mo
2789 TYPE(dbcsr_type), POINTER :: p_inactive_ao
2790 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos_active
2791
2792 ! Transform the AS density matrix P_MO to the atomic orbital basis,
2793 ! this is simply C * P_MO * C^T
2794 nspins = active_space_env%nspins
2795 mos_active => active_space_env%mos_active
2796 DO ispin = 1, nspins
2797 ! size of p_inactive_ao is (nao x nao)
2798 p_inactive_ao => active_space_env%pmat_inactive(ispin)%matrix
2799
2800 ! copy p_inactive_ao to rho_ao
2801 CALL dbcsr_copy(rho_ao(ispin)%matrix, p_inactive_ao)
2802
2803 ! size of p_active_mo is (nmo x nmo)
2804 p_active_mo => active_space_env%p_active(ispin)
2805
2806 ! calculate R = p_mo
2807 CALL cp_fm_create(r, p_active_mo%matrix_struct)
2808 CALL cp_fm_to_fm(p_active_mo, r)
2809
2810 ! calculate U = C * p_mo
2811 CALL get_mo_set(mos_active(ispin), mo_coeff=c_active, nao=nao, nmo=nmo)
2812 CALL cp_fm_create(u, c_active%matrix_struct)
2813 CALL parallel_gemm("N", "N", nao, nmo, nmo, 1.0_dp, c_active, r, 0.0_dp, u)
2814
2815 CALL cp_dbcsr_plus_fm_fm_t(sparse_matrix=rho_ao(ispin)%matrix, &
2816 matrix_v=u, matrix_g=c_active, ncol=nmo, alpha=1.0_dp)
2817
2818 CALL cp_fm_release(r)
2819 CALL cp_fm_release(u)
2820 END DO
2821
2822 END SUBROUTINE update_density_ao
2823
2824! **************************************************************************************************
2825!> \brief Print each value on the master node
2826!> \param this object reference
2827!> \param i i-index
2828!> \param j j-index
2829!> \param k k-index
2830!> \param l l-index
2831!> \param val value of the integral at (i,j,k.l)
2832!> \return always true to dump all integrals
2833! **************************************************************************************************
2834 LOGICAL FUNCTION eri_fcidump_print_func(this, i, j, k, l, val) RESULT(cont)
2835 CLASS(eri_fcidump_print), INTENT(inout) :: this
2836 INTEGER, INTENT(in) :: i, j, k, l
2837 REAL(kind=dp), INTENT(in) :: val
2838
2839 ! write to the actual file only on the master
2840 IF (this%unit_nr > 0) THEN
2841 WRITE (this%unit_nr, "(ES23.16,4I4)") val, i + this%bra_start - 1, j + this%bra_start - 1, &
2842 & k + this%ket_start - 1, l + this%ket_start - 1
2843 END IF
2844
2845 cont = .true.
2846 END FUNCTION eri_fcidump_print_func
2847
2848! **************************************************************************************************
2849!> \brief checksum each value on the master node
2850!> \param this object reference
2851!> \param i i-index
2852!> \param j j-index
2853!> \param k k-index
2854!> \param l l-index
2855!> \param val value of the integral at (i,j,k.l)
2856!> \return always true to dump all integrals
2857! **************************************************************************************************
2858 LOGICAL FUNCTION eri_fcidump_checksum_func(this, i, j, k, l, val) RESULT(cont)
2859 CLASS(eri_fcidump_checksum), INTENT(inout) :: this
2860 INTEGER, INTENT(in) :: i, j, k, l
2861 REAL(kind=dp), INTENT(in) :: val
2862 mark_used(i)
2863 mark_used(j)
2864 mark_used(k)
2865 mark_used(l)
2866
2867 this%checksum = this%checksum + abs(val)
2868
2869 cont = .true.
2870 END FUNCTION eri_fcidump_checksum_func
2871
2872! **************************************************************************************************
2873!> \brief Update active space density matrix from a fortran array
2874!> \param p_act_mo density matrix in active space MO basis
2875!> \param active_space_env active space environment
2876!> \param ispin spin index
2877!> \author Vladimir Rybkin
2878! **************************************************************************************************
2879 SUBROUTINE update_active_density(p_act_mo, active_space_env, ispin)
2880 REAL(kind=dp), DIMENSION(:) :: p_act_mo
2881 TYPE(active_space_type), POINTER :: active_space_env
2882 INTEGER :: ispin
2883
2884 INTEGER :: i1, i2, m1, m2, nmo_active
2885 REAL(kind=dp) :: alpha, pij_new, pij_old
2886 TYPE(cp_fm_type), POINTER :: p_active
2887
2888 p_active => active_space_env%p_active(ispin)
2889 nmo_active = active_space_env%nmo_active
2890 alpha = active_space_env%alpha
2891
2892 DO i1 = 1, nmo_active
2893 m1 = active_space_env%active_orbitals(i1, ispin)
2894 DO i2 = 1, nmo_active
2895 m2 = active_space_env%active_orbitals(i2, ispin)
2896 CALL cp_fm_get_element(p_active, m1, m2, pij_old)
2897 pij_new = p_act_mo(i2 + (i1 - 1)*nmo_active)
2898 pij_new = alpha*pij_new + (1.0_dp - alpha)*pij_old
2899 CALL cp_fm_set_element(p_active, m1, m2, pij_new)
2900 END DO
2901 END DO
2902
2903 END SUBROUTINE update_active_density
2904
2905! **************************************************************************************************
2906!> \brief Compute and print the AS rdm and the natural orbitals occupation numbers
2907!> \param active_space_env active space environment
2908!> \param iw output unit
2909!> \author Stefano Battaglia
2910! **************************************************************************************************
2911 SUBROUTINE print_pmat_noon(active_space_env, iw)
2912 TYPE(active_space_type), POINTER :: active_space_env
2913 INTEGER :: iw
2914
2915 INTEGER :: i1, i2, ii, ispin, jm, m1, m2, &
2916 nmo_active, nspins
2917 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: noon, pmat
2918 TYPE(cp_fm_type), POINTER :: p_active
2919
2920 nspins = active_space_env%nspins
2921 nmo_active = active_space_env%nmo_active
2922
2923 ALLOCATE (noon(nmo_active, nspins))
2924 ALLOCATE (pmat(nmo_active, nmo_active))
2925
2926 DO ispin = 1, nspins
2927 p_active => active_space_env%p_active(ispin)
2928 noon(:, ispin) = 0.0_dp
2929 pmat = 0.0_dp
2930
2931 DO i1 = 1, nmo_active
2932 m1 = active_space_env%active_orbitals(i1, ispin)
2933 DO i2 = 1, nmo_active
2934 m2 = active_space_env%active_orbitals(i2, ispin)
2935 CALL cp_fm_get_element(p_active, m1, m2, pmat(i1, i2))
2936 END DO
2937 END DO
2938
2939 IF (iw > 0) THEN
2940 WRITE (iw, '(/,T3,A,I2,A)') "Active space density matrix for spin ", ispin
2941 DO i1 = 1, nmo_active
2942 DO ii = 1, nmo_active, 8
2943 jm = min(7, nmo_active - ii)
2944 WRITE (iw, '(T3,6(F9.4))') (pmat(i1, ii + i2), i2=0, jm)
2945 END DO
2946 END DO
2947 END IF
2948
2949 ! diagonalize the density matrix
2950 CALL diamat_all(pmat, noon(:, ispin))
2951
2952 IF (iw > 0) THEN
2953 WRITE (iw, '(/,T3,A,I2,A)') "Natural orbitals occupation numbers for spin ", ispin
2954 DO i1 = 1, nmo_active, 8
2955 jm = min(7, nmo_active - i1)
2956 ! noons are stored in ascending order, so reverse-print them
2957 WRITE (iw, '(T3,6(F9.4))') (noon(nmo_active - i1 - i2 + 1, ispin), i2=0, jm)
2958 END DO
2959 END IF
2960
2961 END DO
2962
2963 DEALLOCATE (noon)
2964 DEALLOCATE (pmat)
2965
2966 END SUBROUTINE print_pmat_noon
2967
2968! **************************************************************************************************
2969!> \brief ...
2970!> \param qs_env ...
2971!> \param active_space_env ...
2972!> \param as_input ...
2973! **************************************************************************************************
2974 SUBROUTINE rsdft_embedding(qs_env, active_space_env, as_input)
2975 TYPE(qs_environment_type), POINTER :: qs_env
2976 TYPE(active_space_type), POINTER :: active_space_env
2977 TYPE(section_vals_type), POINTER :: as_input
2978
2979 CHARACTER(len=*), PARAMETER :: routinen = 'rsdft_embedding'
2980 INTEGER :: handle
2981
2982#ifdef __NO_SOCKETS
2983 CALL timeset(routinen, handle)
2984 cpabort("CP2K was compiled with the __NO_SOCKETS option!")
2985 mark_used(qs_env)
2986 mark_used(active_space_env)
2987 mark_used(as_input)
2988#else
2989
2990 INTEGER :: iw, client_fd, socket_fd, iter, max_iter
2991 LOGICAL :: converged, do_scf_embedding, ionode
2992 REAL(kind=dp) :: delta_e, energy_corr, energy_new, &
2993 energy_old, energy_scf, eps_iter, t1, t2
2994 TYPE(cp_logger_type), POINTER :: logger
2995 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: rho_ao
2996 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos_active
2997 TYPE(mp_para_env_type), POINTER :: para_env
2998 TYPE(qs_energy_type), POINTER :: energy
2999 TYPE(qs_ks_env_type), POINTER :: ks_env
3000 TYPE(qs_rho_type), POINTER :: rho
3001
3002 CALL timeset(routinen, handle)
3003
3004 t1 = m_walltime()
3005
3006 logger => cp_get_default_logger()
3007 iw = cp_logger_get_default_io_unit(logger)
3008
3009 CALL get_qs_env(qs_env, para_env=para_env)
3010 ionode = para_env%is_source()
3011
3012 ! get info from the input
3013 CALL section_vals_val_get(as_input, "SCF_EMBEDDING", l_val=do_scf_embedding)
3014 active_space_env%do_scf_embedding = do_scf_embedding
3015 CALL section_vals_val_get(as_input, "MAX_ITER", i_val=max_iter)
3016 IF (max_iter < 0) cpabort("Specify a non-negative number of max iterations.")
3017 CALL section_vals_val_get(as_input, "EPS_ITER", r_val=eps_iter)
3018 IF (eps_iter < 0.0) cpabort("Specify a non-negative convergence threshold.")
3019
3020 ! create the socket and wait for the client to connect
3021 CALL initialize_socket(socket_fd, client_fd, as_input, ionode)
3022 CALL para_env%sync()
3023
3024 ! send two-electron integrals to the client
3025 CALL send_eri_to_client(client_fd, active_space_env, para_env)
3026
3027 ! get pointer to density in ao basis
3028 CALL get_qs_env(qs_env, rho=rho, energy=energy, ks_env=ks_env)
3029 CALL qs_rho_get(rho, rho_ao=rho_ao)
3030
3031 IF (iw > 0) THEN
3032 WRITE (unit=iw, fmt="(/,T2,A,/)") &
3033 "RANGE-SEPARATED DFT EMBEDDING SELF-CONSISTENT OPTIMIZATION"
3034
3035 WRITE (iw, '(T3,A,T68,I12)') "Max. iterations", max_iter
3036 WRITE (iw, '(T3,A,T68,E12.4)') "Conv. threshold", eps_iter
3037 WRITE (iw, '(T3,A,T66,F14.2)') "Density damping", active_space_env%alpha
3038
3039 WRITE (unit=iw, fmt="(/,T3,A,T11,A,T21,A,T34,A,T55,A,T75,A,/,T3,A)") &
3040 "Iter", "Update", "Time", "Corr. energy", "Total energy", "Change", repeat("-", 78)
3041 END IF
3042 ! CALL cp_add_iter_level(logger%iter_info, "QS_SCF")
3043
3044 iter = 0
3045 converged = .false.
3046 ! store the scf energy
3047 energy_scf = active_space_env%energy_ref
3048 energy_new = energy_scf
3049 mos_active => active_space_env%mos_active
3050 ! CALL set_qs_env(qs_env, active_space=active_space_env)
3051
3052 ! start the self-consistent embedding loop
3053 DO WHILE (iter < max_iter)
3054 iter = iter + 1
3055
3056 ! send V_emb and E_ina to the active space solver and update
3057 ! the active space environment with the new active energy and density
3058 CALL send_fock_to_client(client_fd, active_space_env, para_env)
3059
3060 ! update energies
3061 energy_old = energy_new
3062 energy_new = active_space_env%energy_total
3063 energy_corr = energy_new - energy_scf
3064 delta_e = energy_new - energy_old
3065
3066 ! get timer
3067 t2 = t1
3068 t1 = m_walltime()
3069 ! print out progress
3070 IF ((iw > 0)) THEN
3071 WRITE (unit=iw, &
3072 fmt="(T3,I4,T11,A,T19,F6.1,T28,F18.10,T49,F18.10,T70,ES11.2)") &
3073 iter, 'P_Mix', t1 - t2, energy_corr, energy_new, delta_e
3074 CALL m_flush(iw)
3075 END IF
3076
3077 ! update total density in AO basis with the AS contribution
3078 CALL update_density_ao(active_space_env, rho_ao) ! rho_ao is updated
3079
3080 ! calculate F_ks in AO basis (which contains Vxc) with the new density
3081 CALL qs_rho_update_rho(rho, qs_env=qs_env) ! updates rho_r and rho_g using rho_ao
3082 CALL qs_ks_did_change(qs_env%ks_env, rho_changed=.true.) ! set flags about the change
3083 ! Re-evaluate the traces between the density matrix and the core Hamiltonians
3084 CALL evaluate_core_matrix_traces(qs_env)
3085 ! the ks matrix will be rebuilt so this is fine now
3086 ! CALL set_ks_env(qs_env%ks_env, potential_changed=.FALSE.)
3087 CALL qs_ks_build_kohn_sham_matrix(qs_env, calculate_forces=.false., &
3088 just_energy=.false., &
3089 ext_xc_section=active_space_env%xc_section)
3090
3091 ! update the reference energy
3092 active_space_env%energy_ref = energy%total
3093
3094 ! transform KS/Fock, Vxc and Hcore from AO to MO basis
3095 CALL calculate_operators(mos_active, qs_env, active_space_env)
3096
3097 ! calculate the new inactive energy and embedding potential
3098 CALL subspace_fock_matrix(active_space_env)
3099
3100 ! check if it is a one-shot correction
3101 IF (.NOT. active_space_env%do_scf_embedding) THEN
3102 IF (iw > 0) THEN
3103 WRITE (unit=iw, fmt="(/,T3,A,I5,A)") &
3104 "*** one-shot embedding correction finished ***"
3105 END IF
3106 converged = .true.
3107 EXIT
3108 ! check for convergence
3109 ELSEIF (abs(delta_e) <= eps_iter) THEN
3110 IF (iw > 0) THEN
3111 WRITE (unit=iw, fmt="(/,T3,A,I5,A)") &
3112 "*** rs-DFT embedding run converged in ", iter, " iteration(s) ***"
3113 END IF
3114 converged = .true.
3115 EXIT
3116 END IF
3117 END DO
3118
3119 IF (.NOT. converged) THEN
3120 IF (iw > 0) THEN
3121 WRITE (unit=iw, fmt="(/,T3,A,I5,A)") &
3122 "*** rs-DFT embedding did not converged after ", iter, " iteration(s) ***"
3123 END IF
3124 END IF
3125
3126 ! update qs total energy to the final rs-DFT energy
3127 energy%total = active_space_env%energy_total
3128
3129 ! print final energy contributions
3130 IF (iw > 0) THEN
3131 WRITE (unit=iw, fmt="(/,T3,A)") &
3132 "Final energy contributions:"
3133 WRITE (unit=iw, fmt="(T6,A,T56,F20.10)") &
3134 "Inactive energy:", active_space_env%energy_inactive
3135 WRITE (unit=iw, fmt="(T6,A,T56,F20.10)") &
3136 "Active energy:", active_space_env%energy_active
3137 WRITE (unit=iw, fmt="(T6,A,T56,F20.10)") &
3138 "Correlation energy:", energy_corr
3139 WRITE (unit=iw, fmt="(T6,A,T56,F20.10)") &
3140 "Total rs-DFT energy:", active_space_env%energy_total
3141 END IF
3142
3143 ! print the AS rdm and the natural orbital occupation numbers
3144 CALL print_pmat_noon(active_space_env, iw)
3145
3146 CALL finalize_socket(socket_fd, client_fd, as_input, ionode)
3147 CALL para_env%sync()
3148#endif
3149
3150 CALL timestop(handle)
3151
3152 END SUBROUTINE rsdft_embedding
3153
3154#ifndef __NO_SOCKETS
3155! **************************************************************************************************
3156!> \brief Creates the socket, spawns the client and connects to it
3157!> \param socket_fd the socket file descriptor
3158!> \param client_fd the client file descriptor
3159!> \param as_input active space inpute section
3160!> \param ionode logical flag indicating if the process is the master
3161! **************************************************************************************************
3162 SUBROUTINE initialize_socket(socket_fd, client_fd, as_input, ionode)
3163 INTEGER, INTENT(OUT) :: socket_fd, client_fd
3164 TYPE(section_vals_type), INTENT(IN), POINTER :: as_input
3165 LOGICAL, INTENT(IN) :: ionode
3166
3167 CHARACTER(len=*), PARAMETER :: routinen = 'initialize_socket'
3168 INTEGER, PARAMETER :: backlog = 10
3169
3170 CHARACTER(len=default_path_length) :: hostname
3171 INTEGER :: handle, iw, port, protocol
3172 LOGICAL :: inet
3173 TYPE(cp_logger_type), POINTER :: logger
3174
3175 CALL timeset(routinen, handle)
3176
3177 logger => cp_get_default_logger()
3178 iw = cp_logger_get_default_io_unit(logger)
3179
3180 ! protocol == 0 for UNIX, protocol > 0 for INET
3181 CALL section_vals_val_get(as_input, "SOCKET%INET", l_val=inet)
3182 IF (inet) THEN
3183 protocol = 1
3184 ELSE
3185 protocol = 0
3186 END IF
3187 CALL section_vals_val_get(as_input, "SOCKET%HOST", c_val=hostname)
3188 CALL section_vals_val_get(as_input, "SOCKET%PORT", i_val=port)
3189
3190 IF (ionode) THEN
3191 CALL open_bind_socket(socket_fd, protocol, port, trim(hostname)//c_null_char)
3192 WRITE (iw, '(/,T2,A,A)') "@SERVER: Created socket with address ", trim(hostname)
3193 CALL listen_socket(socket_fd, backlog)
3194
3195 ! wait until a connetion request arrives
3196 WRITE (iw, '(T2,A)') "@SERVER: Waiting for requests..."
3197 CALL accept_socket(socket_fd, client_fd)
3198 WRITE (iw, '(T2,A,I2)') "@SERVER: Accepted socket with fd ", client_fd
3199 END IF
3200
3201 CALL timestop(handle)
3202
3203 END SUBROUTINE initialize_socket
3204
3205! **************************************************************************************************
3206!> \brief Closes the connection to the socket and deletes the file
3207!> \param socket_fd the socket file descriptor
3208!> \param client_fd the client file descriptor
3209!> \param as_input active space inpute section
3210!> \param ionode logical flag indicating if the process is the master
3211! **************************************************************************************************
3212 SUBROUTINE finalize_socket(socket_fd, client_fd, as_input, ionode)
3213 INTEGER, INTENT(IN) :: socket_fd, client_fd
3214 TYPE(section_vals_type), INTENT(IN), POINTER :: as_input
3215 LOGICAL, INTENT(IN) :: ionode
3216
3217 CHARACTER(len=*), PARAMETER :: routinen = 'finalize_socket'
3218 INTEGER, PARAMETER :: header_len = 12
3219
3220 CHARACTER(len=default_path_length) :: hostname
3221 INTEGER :: handle
3222
3223 CALL timeset(routinen, handle)
3224
3225 CALL section_vals_val_get(as_input, "SOCKET%HOST", c_val=hostname)
3226
3227 IF (ionode) THEN
3228 ! signal the client to quit
3229 CALL writebuffer(client_fd, "QUIT ", header_len)
3230 ! close the connection
3231 CALL close_socket(client_fd)
3232 CALL close_socket(socket_fd)
3233
3234 ! delete the socket file
3235 IF (file_exists(trim(hostname))) THEN
3236 CALL remove_socket_file(trim(hostname)//c_null_char)
3237 END IF
3238 END IF
3239
3240 CALL timestop(handle)
3241
3242 END SUBROUTINE finalize_socket
3243
3244! **************************************************************************************************
3245!> \brief Sends the two-electron integrals to the client vie the socket
3246!> \param client_fd the client file descriptor
3247!> \param active_space_env active space environment
3248!> \param para_env parallel environment
3249! **************************************************************************************************
3250 SUBROUTINE send_eri_to_client(client_fd, active_space_env, para_env)
3251 INTEGER, INTENT(IN) :: client_fd
3252 TYPE(active_space_type), INTENT(IN), POINTER :: active_space_env
3253 TYPE(mp_para_env_type), INTENT(IN), POINTER :: para_env
3254
3255 CHARACTER(len=*), PARAMETER :: routinen = 'send_eri_to_client'
3256 INTEGER, PARAMETER :: header_len = 12
3257
3258 CHARACTER(len=default_string_length) :: header
3259 INTEGER :: handle, iw
3260 LOGICAL :: ionode
3261 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: eri_aa, eri_ab, eri_bb, s_ab
3262 TYPE(cp_logger_type), POINTER :: logger
3263
3264 CALL timeset(routinen, handle)
3265
3266 logger => cp_get_default_logger()
3267 iw = cp_logger_get_default_io_unit(logger)
3268 ionode = para_env%is_source()
3269
3270 ALLOCATE (eri_aa(active_space_env%nmo_active**4))
3271 CALL eri_to_array(active_space_env%eri, eri_aa, active_space_env%active_orbitals, 1, 1)
3272 IF (active_space_env%nspins == 2) THEN
3273 ALLOCATE (eri_ab(active_space_env%nmo_active**4))
3274 CALL eri_to_array(active_space_env%eri, eri_ab, active_space_env%active_orbitals, 1, 2)
3275 ALLOCATE (eri_bb(active_space_env%nmo_active**4))
3276 CALL eri_to_array(active_space_env%eri, eri_bb, active_space_env%active_orbitals, 2, 2)
3277 ! get the overlap_ab matrix into Fortran array
3278 ALLOCATE (s_ab(active_space_env%nmo_active**2))
3279 associate(act_indices_a => active_space_env%active_orbitals(:, 1), &
3280 act_indices_b => active_space_env%active_orbitals(:, 2))
3281 CALL subspace_matrix_to_array(active_space_env%sab_sub(1), s_ab, act_indices_a, act_indices_b)
3282 END associate
3283 END IF
3284
3285 ! ask the status of the client
3286 IF (ionode) CALL writebuffer(client_fd, "STATUS ", header_len)
3287 DO
3288 header = ""
3289 CALL para_env%sync()
3290 IF (ionode) THEN
3291 ! IF (iw > 0) WRITE(iw, *) "@SERVER: Waiting for messages..."
3292 CALL readbuffer(client_fd, header, header_len)
3293 END IF
3294 CALL para_env%bcast(header, para_env%source)
3295
3296 ! IF (iw > 0) WRITE(iw, *) "@SERVER: Message from client: ", TRIM(header)
3297
3298 IF (trim(header) == "READY") THEN
3299 ! if the client is ready, send the data
3300 CALL para_env%sync()
3301 IF (ionode) THEN
3302 CALL writebuffer(client_fd, "TWOBODY ", header_len)
3303 CALL writebuffer(client_fd, active_space_env%nspins)
3304 CALL writebuffer(client_fd, active_space_env%nmo_active)
3305 CALL writebuffer(client_fd, active_space_env%nelec_active)
3306 CALL writebuffer(client_fd, active_space_env%multiplicity)
3307 ! send the alpha component
3308 CALL writebuffer(client_fd, eri_aa, SIZE(eri_aa))
3309 ! send the beta part for unrestricted calculations
3310 IF (active_space_env%nspins == 2) THEN
3311 CALL writebuffer(client_fd, eri_ab, SIZE(eri_ab))
3312 CALL writebuffer(client_fd, eri_bb, SIZE(eri_bb))
3313 CALL writebuffer(client_fd, s_ab, SIZE(s_ab))
3314 END IF
3315 END IF
3316 ELSE IF (trim(header) == "RECEIVED") THEN
3317 EXIT
3318 END IF
3319 END DO
3320
3321 DEALLOCATE (eri_aa)
3322 IF (active_space_env%nspins == 2) THEN
3323 DEALLOCATE (eri_ab)
3324 DEALLOCATE (eri_bb)
3325 DEALLOCATE (s_ab)
3326 END IF
3327
3328 CALL para_env%sync()
3329
3330 CALL timestop(handle)
3331
3332 END SUBROUTINE send_eri_to_client
3333
3334! **************************************************************************************************
3335!> \brief Sends the one-electron embedding potential and the inactive energy to the client
3336!> \param client_fd the client file descriptor
3337!> \param active_space_env active space environment
3338!> \param para_env parallel environment
3339! **************************************************************************************************
3340 SUBROUTINE send_fock_to_client(client_fd, active_space_env, para_env)
3341 INTEGER, INTENT(IN) :: client_fd
3342 TYPE(active_space_type), INTENT(IN), POINTER :: active_space_env
3343 TYPE(mp_para_env_type), INTENT(IN), POINTER :: para_env
3344
3345 CHARACTER(len=*), PARAMETER :: routinen = 'send_fock_to_client'
3346 INTEGER, PARAMETER :: header_len = 12
3347
3348 CHARACTER(len=default_string_length) :: header
3349 INTEGER :: handle, iw
3350 LOGICAL :: debug, ionode
3351 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: fock_a, fock_b, p_act_mo_a, p_act_mo_b
3352 TYPE(cp_logger_type), POINTER :: logger
3353
3354 CALL timeset(routinen, handle)
3355
3356 ! Set to .TRUE. to activate debug output
3357 debug = .false.
3358
3359 logger => cp_get_default_logger()
3360 iw = cp_logger_get_default_io_unit(logger)
3361 ionode = para_env%is_source()
3362
3363 ALLOCATE (p_act_mo_a(active_space_env%nmo_active**2))
3364 ALLOCATE (fock_a(active_space_env%nmo_active**2))
3365 IF (active_space_env%nspins == 2) THEN
3366 ALLOCATE (p_act_mo_b(active_space_env%nmo_active**2))
3367 ALLOCATE (fock_b(active_space_env%nmo_active**2))
3368 END IF
3369
3370 ! get the fock matrix into Fortran arrays
3371 associate(act_indices => active_space_env%active_orbitals(:, 1))
3372 CALL subspace_matrix_to_array(active_space_env%fock_sub(1), fock_a, act_indices, act_indices)
3373 END associate
3374
3375 IF (active_space_env%nspins == 2) THEN
3376 associate(act_indices => active_space_env%active_orbitals(:, 2))
3377 CALL subspace_matrix_to_array(active_space_env%fock_sub(2), fock_b, act_indices, act_indices)
3378 END associate
3379 END IF
3380
3381 ! ask the status of the client
3382 IF (ionode) CALL writebuffer(client_fd, "STATUS ", header_len)
3383 DO
3384 header = ""
3385
3386 CALL para_env%sync()
3387 IF (ionode) THEN
3388 IF (debug .AND. iw > 0) WRITE (iw, *) "@SERVER: Waiting for messages..."
3389 CALL readbuffer(client_fd, header, header_len)
3390 END IF
3391 CALL para_env%bcast(header, para_env%source)
3392
3393 IF (debug .AND. iw > 0) WRITE (iw, *) "@SERVER: Message from client: ", trim(header)
3394
3395 IF (trim(header) == "READY") THEN
3396 ! if the client is ready, send the data
3397 CALL para_env%sync()
3398 IF (ionode) THEN
3399 CALL writebuffer(client_fd, "ONEBODY ", header_len)
3400 CALL writebuffer(client_fd, active_space_env%energy_inactive)
3401 ! send the alpha component
3402 CALL writebuffer(client_fd, fock_a, SIZE(fock_a))
3403 ! send the beta part for unrestricted calculations
3404 IF (active_space_env%nspins == 2) THEN
3405 CALL writebuffer(client_fd, fock_b, SIZE(fock_b))
3406 END IF
3407 END IF
3408
3409 ELSE IF (trim(header) == "HAVEDATA") THEN
3410 ! qiskit has data to transfer, let them know we want it and wait for it
3411 CALL para_env%sync()
3412 IF (ionode) THEN
3413 IF (debug .AND. iw > 0) WRITE (iw, *) "@SERVER: Qiskit has data to transfer"
3414 CALL writebuffer(client_fd, "GETDENSITY ", header_len)
3415
3416 ! read the active energy and density
3417 CALL readbuffer(client_fd, active_space_env%energy_active)
3418 CALL readbuffer(client_fd, p_act_mo_a, SIZE(p_act_mo_a))
3419 IF (active_space_env%nspins == 2) THEN
3420 CALL readbuffer(client_fd, p_act_mo_b, SIZE(p_act_mo_b))
3421 END IF
3422 END IF
3423
3424 ! broadcast the data to all processors
3425 CALL para_env%bcast(active_space_env%energy_active, para_env%source)
3426 CALL para_env%bcast(p_act_mo_a, para_env%source)
3427 IF (active_space_env%nspins == 2) THEN
3428 CALL para_env%bcast(p_act_mo_b, para_env%source)
3429 END IF
3430
3431 ! update total and reference energies in active space enviornment
3432 active_space_env%energy_total = active_space_env%energy_inactive + active_space_env%energy_active
3433
3434 ! update the active density matrix in the active space environment
3435 CALL update_active_density(p_act_mo_a, active_space_env, 1)
3436 IF (active_space_env%nspins == 2) THEN
3437 CALL update_active_density(p_act_mo_b, active_space_env, 2)
3438 END IF
3439
3440 ! the non-iterative part is done, we can continue
3441 EXIT
3442 END IF
3443
3444 END DO
3445
3446 DEALLOCATE (p_act_mo_a)
3447 DEALLOCATE (fock_a)
3448 IF (active_space_env%nspins == 2) THEN
3449 DEALLOCATE (p_act_mo_b)
3450 DEALLOCATE (fock_b)
3451 END IF
3452
3453 CALL para_env%sync()
3454
3455 CALL timestop(handle)
3456
3457 END SUBROUTINE send_fock_to_client
3458#endif
3459
3460END MODULE qs_active_space_methods
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:593
subroutine, public admm_env_release(admm_env)
releases the ADMM environment, cleans up all types
Definition admm_types.F:426
Define the atomic kind types and their sub types.
pure real(dp) function, public srules(z, ne, n, l)
...
subroutine, public deallocate_sto_basis_set(sto_basis_set)
...
subroutine, public allocate_sto_basis_set(sto_basis_set)
...
subroutine, public create_gto_from_sto_basis(sto_basis_set, gto_basis_set, ngauss, ortho)
...
subroutine, public set_sto_basis_set(sto_basis_set, name, nshell, symbol, nq, lq, zet)
...
subroutine, public init_orb_basis_set(gto_basis_set)
Initialise a Gaussian-type orbital (GTO) basis set data set.
Handles all functions related to the CELL.
subroutine, public write_cell_low(cell, unit_str, output_unit, label)
Write the cell parameters to the output unit.
subroutine, public set_cell_param(cell, cell_length, cell_angle, periodic, do_init_cell)
Sets the cell using the internal parameters (a,b,c) (alpha,beta,gamma) using the convention: a parall...
subroutine, public init_cell(cell, hmat, periodic)
Initialise/readjust a simulation cell after hmat has been changed.
Handles all functions related to the CELL.
Definition cell_types.F:15
integer, parameter, public use_perd_xyz
Definition cell_types.F:42
integer, parameter, public use_perd_none
Definition cell_types.F:42
methods related to the blacs parallel environment
integer, parameter, public blacs_grid_square
subroutine, public cp_blacs_env_release(blacs_env)
releases the given blacs_env
subroutine, public cp_blacs_env_create(blacs_env, para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
allocates and initializes a type that represent a blacs context
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_iterator_next_block(iterator, row, column, block, block_number_argument_has_been_removed, row_size, col_size, row_offset, col_offset)
...
logical function, public dbcsr_iterator_blocks_left(iterator)
...
subroutine, public dbcsr_iterator_stop(iterator)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_multiply(transa, transb, alpha, matrix_a, matrix_b, beta, matrix_c, first_row, last_row, first_column, last_column, first_k, last_k, retain_sparsity, filter_eps, flop)
...
subroutine, public dbcsr_get_info(matrix, nblkrows_total, nblkcols_total, nfullrows_total, nfullcols_total, nblkrows_local, nblkcols_local, nfullrows_local, nfullcols_local, my_prow, my_pcol, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, row_blk_offset, col_blk_offset, distribution, name, matrix_type, group)
...
real(kind=dp) function, public dbcsr_get_occupation(matrix)
...
subroutine, public dbcsr_iterator_start(iterator, matrix, shared, dynamic, dynamic_byrows)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_release(matrix)
...
DBCSR operations in CP2K.
subroutine, public cp_dbcsr_sm_fm_multiply(matrix, fm_in, fm_out, ncol, alpha, beta)
multiply a dbcsr with a fm matrix
subroutine, public copy_dbcsr_to_fm(matrix, fm)
Copy a DBCSR matrix to a BLACS matrix.
subroutine, public cp_dbcsr_plus_fm_fm_t(sparse_matrix, matrix_v, matrix_g, ncol, alpha, keep_sparsity, symmetry_mode)
performs the multiplication sparse_matrix+dense_mat*dens_mat^T if matrix_g is not explicitly given,...
subroutine, public cp_dbcsr_m_by_n_from_template(matrix, template, m, n, sym)
Utility function to create an arbitrary shaped dbcsr matrix with the same processor grid as the templ...
DBCSR output in CP2K.
subroutine, public cp_dbcsr_write_sparse_matrix(sparse_matrix, before, after, qs_env, para_env, first_row, last_row, first_col, last_col, scale, output_unit, omit_headers)
...
Utility routines to open and close files. Tracking of preconnections.
Definition cp_files.F:16
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
Definition cp_files.F:311
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
Definition cp_files.F:122
logical function, public file_exists(file_name)
Checks if file exists, considering also the file discovery mechanism.
Definition cp_files.F:504
Basic linear algebra operations for full matrices.
subroutine, public cp_fm_column_scale(matrixa, scaling)
scales column i of matrix a with scaling(i)
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, use_sp, nrow, ncol, set_zero)
creates a new full matrix with the given structure
subroutine, public cp_fm_get_element(matrix, irow_global, icol_global, alpha, local)
returns an element of a fm this value is valid on every cpu using this call is expensive
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_set_element(matrix, irow_global, icol_global, alpha)
sets an element of a matrix
subroutine, public cp_fm_init_random(matrix, ncol, start_col)
fills a matrix with random numbers
subroutine, public cp_fm_write_formatted(fm, unit, header, value_format)
Write out a full matrix in plain text.
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
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer, parameter, public debug_print_level
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
integer, parameter, public low_print_level
integer, parameter, public medium_print_level
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
integer, parameter, public cp_p_file
integer, parameter, public high_print_level
integer function, public cp_print_key_should_output(iteration_info, basis_section, print_key_path, used_print_key, first_time)
returns what should be done with the given property if btest(res,cp_p_store) then the property should...
integer, parameter, public silent_print_level
A wrapper around pw_to_cube() which accepts particle_list_type.
subroutine, public cp_pw_to_cube(pw, unit_nr, title, particles, zeff, stride, max_file_size_mb, zero_tails, silent, mpi_io)
...
Module to compute the error function of a complex argument.
Definition erf_complex.F:50
elemental complex(kind=dp) function, public erfz_fast(z)
Computes the error function of a complex argument using the Poppe and Wijers algorithm.
Types to describe group distributions.
Types and set/get functions for HFX.
Definition hfx_types.F:15
subroutine, public hfx_create(x_data, para_env, hfx_section, atomic_kind_set, qs_kind_set, particle_set, dft_control, cell, orb_basis, ri_basis, nelectron_total, nkp_grid)
This routine allocates and initializes all types in hfx_data
Definition hfx_types.F:595
subroutine, public hfx_release(x_data)
This routine deallocates all data structures
Definition hfx_types.F:1910
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public eri_operator_erf
integer, parameter, public qiskit_solver
integer, parameter, public no_solver
integer, parameter, public wannier_projection
integer, parameter, public mao_projection
integer, parameter, public eri_method_full_gpw
integer, parameter, public casci_canonical
integer, parameter, public manual_selection
integer, parameter, public eri_operator_gaussian
integer, parameter, public eri_method_gpw_ht
integer, parameter, public eri_operator_erfc
integer, parameter, public eri_poisson_mt
integer, parameter, public eri_poisson_analytic
integer, parameter, public eri_operator_trunc
integer, parameter, public eri_poisson_periodic
integer, parameter, public eri_operator_coulomb
integer, parameter, public eri_operator_yukawa
integer, parameter, public eri_operator_lr_trunc
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
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_set_subs_vals(section_vals, subsection_name, new_section_vals, i_rep_section)
replaces of the requested subsection with the one given
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 int_8
Definition kinds.F:54
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_string_length
Definition kinds.F:57
integer, parameter, public default_path_length
Definition kinds.F:58
Machine interface based on Fortran 2003 and POSIX.
Definition machine.F:17
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Definition machine.F:136
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition machine.F:153
Definition of mathematical constants and functions.
real(kind=dp), parameter, public pi
real(kind=dp), parameter, public rootpi
real(kind=dp), parameter, public fourpi
real(kind=dp), parameter, public twopi
Collection of simple mathematical functions and subroutines.
Definition mathlib.F:15
subroutine, public diamat_all(a, eigval, dac)
Diagonalize the symmetric n by n matrix a using the LAPACK library. Only the upper triangle of matrix...
Definition mathlib.F:381
Utility routines for the memory handling.
Interface to the message passing library MPI.
subroutine, public mp_para_env_release(para_env)
releases the para object (to be called when you don't want anymore the shared copy of this object)
Calls routines to get RI integrals and calculate total energies.
Definition mp2_gpw.F:14
subroutine, public grep_rows_in_subgroups(para_env, para_env_sub, mo_coeff, gd_array, c)
...
Definition mp2_gpw.F:758
subroutine, public build_dbcsr_from_rows(para_env_sub, mo_coeff_to_build, cread, mat_munu, gd_array, eps_filter)
Encapsulate the building of dbcsr_matrices mo_coeff_(v,o,all)
Definition mp2_gpw.F:886
subroutine, public create_mat_munu(mat_munu, qs_env, eps_grid, blacs_env_sub, do_ri_aux_basis, do_mixed_basis, group_size_prim, do_alloc_blocks_from_nbl, do_kpoints, sab_orb_sub, dbcsr_sym_type)
Encapsulate the building of dbcsr_matrix mat_munu.
Definition mp2_gpw.F:989
integer, parameter, public mt0d
Definition mt_util.F:33
basic linear algebra operations for full matrixes
represent a simple array based list of the given type
Define the data structure for the particle information.
Periodic Table related data definitions.
type(atom), dimension(0:nelem), public ptable
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public angstrom
Definition physcon.F:144
real(kind=dp), parameter, public bohr
Definition physcon.F:147
types of preconditioners
computes preconditioners, and implements methods to apply them currently used in qs_ot
methods of pw_env that have dependence on qs_env
subroutine, public pw_env_rebuild(pw_env, qs_env, external_para_env)
rebuilds the pw_env data (necessary if cell or cutoffs change)
subroutine, public pw_env_create(pw_env)
creates a pw_env, if qs_env is given calls pw_env_rebuild
container for various plainwaves related things
subroutine, public pw_env_release(pw_env, para_env)
releases the given pw_env (see doc/ReferenceCounting.html)
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
subroutine, public pw_gauss_damp(pw, omega)
Multiply all data points with a Gaussian damping factor Needed for longrange Coulomb potential V(\vec...
subroutine, public pw_compl_gauss_damp(pw, omega)
Multiply all data points with a Gaussian damping factor Needed for longrange Coulomb potential V(\vec...
functions related to the poisson solver on regular grids
integer, parameter, public pw_poisson_periodic
integer, parameter, public periodic3d
integer, parameter, public analytic0d
integer, parameter, public pw_poisson_analytic
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
The module to read/write QCSchema HDF5 files for interfacing CP2K with other programs.
Definition qcschema.F:14
subroutine, public qcschema_env_release(qcschema_env)
Releases the allocated memory of a qcschema environment.
Definition qcschema.F:609
subroutine, public qcschema_env_create(qcschema_env, qs_env)
Create and initialize a qcschema object from a quickstep environment.
Definition qcschema.F:272
subroutine, public qcschema_to_hdf5(qcschema_env, filename)
Writes a qcschema object to an hdf5 file.
Definition qcschema.F:739
Determine active space Hamiltonian.
subroutine eri_fcidump_set(this, bra_start, ket_start)
Sets the starting indices of the bra and ket.
subroutine, public active_space_main(qs_env)
Main method for determining the active space Hamiltonian.
The types needed for the calculation of active space Hamiltonians.
subroutine, public csr_idx_from_combined(ij, n, i, j)
extracts indices i and j from combined index ij
integer function, public csr_idx_to_combined(i, j, n)
calculates combined index (ij)
integer function, dimension(2), public get_irange_csr(nindex, mp_group)
calculates index range for processor in group mp_group
subroutine, public create_active_space_type(active_space_env)
Creates an active space environment type, nullifying all quantities.
Contains utility routines for the active space module.
subroutine, public eri_to_array(eri_env, array, active_orbitals, spin1, spin2)
Copy the eri tensor for spins isp1 and isp2 to a standard 1D Fortran array.
subroutine, public subspace_matrix_to_array(source_matrix, target_array, row_index, col_index)
Copy a (square portion) of a cp_fm_type matrix to a standard 1D Fortran array.
Calculate the plane wave density by collocating the primitive Gaussian functions (pgf).
subroutine, public calculate_wavefunction(mo_vectors, ivector, rho, rho_gspace, atomic_kind_set, qs_kind_set, cell, dft_control, particle_set, pw_env, basis_type)
maps a given wavefunction on the grid
collects routines that calculate density matrices
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, 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, 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.
Integrate single or product functions over a potential on a RS grid.
Define the quickstep kind type and their sub types.
routines that build the Kohn-Sham matrix (i.e calculate the coulomb and xc parts
subroutine, public evaluate_core_matrix_traces(qs_env)
Calculates the traces of the core matrices and the density matrix.
subroutine, public qs_ks_update_qs_env(qs_env, calculate_forces, just_energy, print_active)
updates the Kohn Sham matrix of the given qs_env (facility method)
subroutine, public qs_ks_build_kohn_sham_matrix(qs_env, calculate_forces, just_energy, print_active, ext_ks_matrix, ext_xc_section)
routine where the real calculations are made: the KS matrix is calculated
subroutine, public set_ks_env(ks_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, complex_ks, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, kinetic, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_ks_im_kp, vppl, rho_core, rho_nlcc, rho_nlcc_g, vee, neighbor_list_id, kpoints, sab_orb, sab_all, sac_ae, sac_ppl, sac_lri, sap_ppnl, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_vdw, sab_scp, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, task_list, task_list_soft, subsys, dft_control, dbcsr_dist, distribution_2d, pw_env, para_env, blacs_env)
...
subroutine, public qs_ks_did_change(ks_env, s_mstruct_changed, rho_changed, potential_changed, full_reset)
tells that some of the things relevant to the ks calculation did change. has to be called when change...
Definition and initialisation of the mo data type.
Definition qs_mo_io.F:21
subroutine, public write_mo_set_to_output_unit(mo_set, qs_kind_set, particle_set, dft_section, before, kpoint, final_mos, spin, solver_method, rtp, cpart, sim_step, umo_set)
Write MO information to output file (eigenvalues, occupation numbers, coefficients)
Definition qs_mo_io.F:1011
collects routines that perform operations directly related to MOs
Definition and initialisation of the mo data type.
Definition qs_mo_types.F:22
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.
subroutine, public init_mo_set(mo_set, fm_pool, fm_ref, fm_struct, name)
initializes an allocated mo_set. eigenvalues, mo_coeff, occupation_numbers are valid only after this ...
Define the neighbor list data types and the corresponding functionality.
subroutine, public release_neighbor_list_sets(nlists)
releases an array of neighbor_list_sets
an eigen-space solver for the generalised symmetric eigenvalue problem for sparse matrices,...
subroutine, public ot_eigensolver(matrix_h, matrix_s, matrix_orthogonal_space_fm, matrix_c_fm, preconditioner, eps_gradient, iter_max, size_ortho_space, silent, ot_settings)
...
methods of the rho structure (defined in qs_rho_types)
subroutine, public qs_rho_update_rho(rho_struct, qs_env, rho_xc_external, local_rho_set, task_list_external, task_list_external_soft, pw_env_external, para_env_external)
updates rho_r and rho_g to the rhorho_ao. if use_kinetic_energy_density also computes tau_r and tau_g...
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...
Utility routines for qs_scf.
subroutine, public qs_scf_compute_properties(qs_env, wf_type, do_mp2)
computes properties for a given hamilonian using the current wfn
types that represent a quickstep subsys
subroutine, public qs_subsys_get(subsys, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell, cell_ref, use_ref_cell, energy, force, qs_kind_set, cp_subsys, nelectron_total, nelectron_spin)
...
parameters that control an scf iteration
Implements UNIX and INET sockets.
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)
...
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
All kind of helpful little routines.
Definition util.F:14
pure integer function, dimension(2), public get_limit(m, n, me)
divide m entries into n parts, return size of part me
Definition util.F:333
void open_bind_socket(int *psockfd, int *inet, int *port, char *host)
Opens and binds a socket.
Definition sockets.c:137
void writebuffer(int *psockfd, char *data, int *plen)
Writes to a socket.
Definition sockets.c:201
void accept_socket(int *psockfd, int *pclientfd)
Listens to a socket.
Definition sockets.c:256
void close_socket(int *psockfd)
Closes a socket.
Definition sockets.c:267
void listen_socket(int *psockfd, int *backlog)
Listens to a socket.
Definition sockets.c:243
void readbuffer(int *psockfd, char *data, int *plen)
Reads from a socket.
Definition sockets.c:219
void remove_socket_file(char *host)
Removes a socket file.
Definition sockets.c:273
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...
stores all the informations relevant to an mpi environment
contained for different pw related things
contains all the informations needed by the fft based poisson solvers
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 ...
The full QCSchema output type. For more information refer to: https://molssi-qc-schema....
Definition qcschema.F:253
Abstract function object for the eri_type_eri_foreach method.
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.