147#include "./base/base_uses.f90"
152 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'xas_tdp_methods'
170 CHARACTER(len=*),
PARAMETER :: routinen =
'xas_tdp'
172 CHARACTER(default_string_length) :: rst_filename
173 INTEGER :: handle, n_rep, output_unit
174 LOGICAL :: do_restart, do_rixs
177 CALL timeset(routinen, handle)
180 NULLIFY (xas_tdp_section)
191 IF (output_unit > 0)
THEN
192 WRITE (unit=output_unit, fmt=
"(/,T3,A,/,T3,A,/,T3,A,/,T3,A,/)") &
193 "!===========================================================================!", &
195 "! Starting TDDFPT driven X-rays absorption spectroscopy calculations !", &
196 "!===========================================================================!"
214 IF (output_unit > 0)
THEN
215 WRITE (unit=output_unit, fmt=
"(/,T3,A)") &
216 "# This is a RESTART calculation for PDOS and/or CUBE printing"
219 CALL restart_calculation(rst_filename, xas_tdp_section, qs_env)
223 IF (
PRESENT(rixs_env))
THEN
224 CALL xas_tdp_core(xas_tdp_section, qs_env, rixs_env)
226 CALL xas_tdp_core(xas_tdp_section, qs_env)
230 IF (output_unit > 0)
THEN
231 WRITE (unit=output_unit, fmt=
"(/,T3,A,/,T3,A,/,T3,A,/)") &
232 "!===========================================================================!", &
233 "! End of TDDFPT driven X-rays absorption spectroscopy calculations !", &
234 "!===========================================================================!"
237 CALL timestop(handle)
247 SUBROUTINE xas_tdp_core(xas_tdp_section, qs_env, rixs_env)
253 CHARACTER(LEN=default_string_length) :: kind_name
254 INTEGER :: batch_size, bo(2), current_state_index, iat, iatom, ibatch, ikind, ispin, istate, &
255 nbatch, nex_atom, output_unit, tmp_index
256 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: batch_atoms, ex_atoms_of_kind
257 INTEGER,
DIMENSION(:),
POINTER :: atoms_of_kind
258 LOGICAL :: do_os, do_rixs, end_of_batch, unique
265 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
270 NULLIFY (xas_tdp_env, xas_tdp_control, atomic_kind_set, atoms_of_kind, current_state)
271 NULLIFY (xas_atom_env, dft_control, matrix_ks, admm_env, qs_kind_set, tmp_basis)
276 IF (output_unit > 0)
THEN
277 WRITE (unit=output_unit, fmt=
"(/,T3,A)") &
278 "# Create and initialize the XAS_TDP environment"
280 CALL get_qs_env(qs_env, dft_control=dft_control, do_rixs=do_rixs)
281 IF (
PRESENT(rixs_env))
THEN
282 CALL xas_tdp_init(xas_tdp_env, xas_tdp_control, qs_env, rixs_env)
286 CALL print_info(output_unit, xas_tdp_control, qs_env)
288 IF (output_unit > 0)
THEN
289 IF (xas_tdp_control%check_only)
THEN
290 cpwarn(
"This is a CHECK_ONLY run for donor MOs verification")
295 IF (xas_tdp_control%do_loc)
THEN
296 IF (output_unit > 0)
THEN
297 WRITE (unit=output_unit, fmt=
"(/,T3,A,/)") &
298 "# Localizing core orbitals for better identification"
301 IF (xas_tdp_control%do_uks)
THEN
302 DO ispin = 1, dft_control%nspins
304 xas_tdp_control%print_loc_subsection, myspin=ispin)
308 xas_tdp_control%print_loc_subsection, myspin=1)
313 CALL find_mo_centers(xas_tdp_env, xas_tdp_control, qs_env)
316 CALL assign_mos_to_ex_atoms(xas_tdp_env, xas_tdp_control, qs_env)
319 IF (xas_tdp_control%do_loc)
THEN
320 IF (output_unit > 0)
THEN
321 WRITE (unit=output_unit, fmt=
"(/,T3,A,/,T5,A)") &
322 "# Diagonalize localized MOs wrt the KS matrix in the subspace of each excited", &
323 "atom for better donor state identification."
325 CALL diagonalize_assigned_mo_subset(xas_tdp_env, xas_tdp_control, qs_env)
327 CALL find_mo_centers(xas_tdp_env, xas_tdp_control, qs_env)
330 IF (output_unit > 0)
THEN
331 WRITE (unit=output_unit, fmt=
"(/,T3,A,I4,A,/)") &
332 "# Assign the relevant subset of the ", xas_tdp_control%n_search, &
333 " lowest energy MOs to excited atoms"
335 CALL write_mos_to_ex_atoms_association(xas_tdp_env, xas_tdp_control, qs_env)
338 IF (xas_tdp_control%check_only)
CALL print_checks(xas_tdp_env, xas_tdp_control, qs_env)
342 IF ((xas_tdp_control%do_xc .OR. xas_tdp_control%do_soc .OR. xas_tdp_control%do_gw2x) &
343 .AND. .NOT. xas_tdp_control%check_only)
THEN
345 IF (output_unit > 0 .AND. xas_tdp_control%do_xc)
THEN
346 WRITE (unit=output_unit, fmt=
"(/,T3,A,I4,A)") &
347 "# Integrating the xc kernel on the atomic grids ..."
353 do_os = xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks
355 IF (xas_tdp_control%do_xc .AND. (.NOT. xas_tdp_control%xps_only))
THEN
359 IF (xas_tdp_control%do_soc .OR. xas_tdp_control%do_gw2x)
THEN
367 IF ((.NOT. (xas_tdp_control%check_only .OR. xas_tdp_control%xps_only)) .AND. &
368 (xas_tdp_control%do_xc .OR. xas_tdp_control%do_coulomb))
THEN
369 IF (output_unit > 0)
THEN
370 WRITE (unit=output_unit, fmt=
"(/,T3,A,I4,A)") &
371 "# Computing the RI 3-center Coulomb integrals ..."
379 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
380 current_state_index = 1
383 DO ikind = 1,
SIZE(atomic_kind_set)
385 IF (xas_tdp_control%check_only)
EXIT
386 IF (.NOT. any(xas_tdp_env%ex_kind_indices == ikind)) cycle
388 CALL get_atomic_kind(atomic_kind=atomic_kind_set(ikind), name=kind_name, &
389 atom_list=atoms_of_kind)
393 IF (xas_tdp_control%do_hfx)
THEN
401 CALL get_ri_3c_batches(ex_atoms_of_kind, nbatch, batch_size, atoms_of_kind, xas_tdp_env)
402 nex_atom =
SIZE(ex_atoms_of_kind)
405 DO ibatch = 1, nbatch
407 bo =
get_limit(nex_atom, nbatch, ibatch - 1)
408 batch_size = bo(2) - bo(1) + 1
409 ALLOCATE (batch_atoms(batch_size))
411 DO iat = bo(1), bo(2)
413 batch_atoms(iatom) = ex_atoms_of_kind(iat)
418 IF (xas_tdp_control%do_hfx)
THEN
419 IF (output_unit > 0)
THEN
420 WRITE (unit=output_unit, fmt=
"(/,T3,A,I4,A,I4,A,I1,A,A)") &
421 "# Computing the RI 3-center Exchange integrals for batch ", ibatch,
"(/", nbatch,
") of ", &
422 batch_size,
" atoms of kind: ", trim(kind_name)
429 DO iat = 1, batch_size
430 iatom = batch_atoms(iat)
432 tmp_index =
locate(xas_tdp_env%ex_atom_indices, iatom)
436 IF (xas_tdp_control%dipole_form ==
xas_dip_len .OR. xas_tdp_control%do_quad)
THEN
437 CALL compute_lenrep_multipole(iatom, xas_tdp_env, xas_tdp_control, qs_env)
441 DO istate = 1,
SIZE(xas_tdp_env%state_types, 1)
443 IF (xas_tdp_env%state_types(istate, tmp_index) ==
xas_not_excited) cycle
445 current_state => xas_tdp_env%donor_states(current_state_index)
447 at_symbol=kind_name, kind_index=ikind, &
448 state_type=xas_tdp_env%state_types(istate, tmp_index))
451 IF (output_unit > 0)
THEN
452 WRITE (unit=output_unit, fmt=
"(/,T3,A,A2,A,I4,A,A,/)") &
453 "# Start of calculations for donor state of type ", &
454 xas_tdp_env%state_type_char(current_state%state_type),
" for atom", &
455 current_state%at_index,
" of kind ", trim(current_state%at_symbol)
460 CALL assign_mos_to_donor_state(current_state, xas_tdp_env, xas_tdp_control, qs_env)
463 CALL perform_mulliken_on_donor_state(current_state, qs_env)
466 IF (xas_tdp_control%do_gw2x)
THEN
467 CALL gw2x_shift(current_state, xas_tdp_env, xas_tdp_control, qs_env)
471 IF (.NOT. xas_tdp_control%xps_only)
THEN
474 IF (xas_tdp_control%do_spin_cons)
THEN
477 CALL compute_dipole_fosc(current_state, xas_tdp_control, xas_tdp_env)
478 IF (xas_tdp_control%do_quad)
CALL compute_quadrupole_fosc(current_state, &
479 xas_tdp_control, xas_tdp_env)
481 xas_tdp_section, qs_env)
482 CALL write_donor_state_restart(
tddfpt_spin_cons, current_state, xas_tdp_section, qs_env)
485 IF (xas_tdp_control%do_spin_flip)
THEN
490 xas_tdp_section, qs_env)
491 CALL write_donor_state_restart(
tddfpt_spin_flip, current_state, xas_tdp_section, qs_env)
494 IF (xas_tdp_control%do_singlet)
THEN
497 CALL compute_dipole_fosc(current_state, xas_tdp_control, xas_tdp_env)
498 IF (xas_tdp_control%do_quad)
CALL compute_quadrupole_fosc(current_state, &
499 xas_tdp_control, xas_tdp_env)
501 xas_tdp_section, qs_env)
502 CALL write_donor_state_restart(
tddfpt_singlet, current_state, xas_tdp_section, qs_env)
505 IF (xas_tdp_control%do_triplet)
THEN
510 xas_tdp_section, qs_env)
511 CALL write_donor_state_restart(
tddfpt_triplet, current_state, xas_tdp_section, qs_env)
515 IF (xas_tdp_control%do_soc .AND. current_state%state_type ==
xas_2p_type)
THEN
516 IF (xas_tdp_control%do_singlet .AND. xas_tdp_control%do_triplet)
THEN
517 CALL include_rcs_soc(current_state, xas_tdp_env, xas_tdp_control, qs_env)
519 IF (xas_tdp_control%do_spin_cons .AND. xas_tdp_control%do_spin_flip)
THEN
520 CALL include_os_soc(current_state, xas_tdp_env, xas_tdp_control, qs_env)
525 CALL print_xas_tdp_to_file(current_state, xas_tdp_env, xas_tdp_control, xas_tdp_section)
527 IF (xas_tdp_control%do_gw2x)
CALL print_xps(current_state, xas_tdp_env, xas_tdp_control, qs_env)
531 current_state_index = current_state_index + 1
532 NULLIFY (current_state)
536 end_of_batch = .false.
537 IF (iat == batch_size) end_of_batch = .true.
540 DEALLOCATE (batch_atoms)
542 DEALLOCATE (ex_atoms_of_kind)
546 IF (dft_control%do_admm)
THEN
547 CALL get_qs_env(qs_env, matrix_ks=matrix_ks, admm_env=admm_env)
548 DO ispin = 1, dft_control%nspins
554 IF (xas_tdp_control%eps_pgf > 0.0_dp)
THEN
555 CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set)
556 DO ikind = 1,
SIZE(atomic_kind_set)
557 CALL get_qs_kind(qs_kind_set(ikind), basis_set=tmp_basis, basis_type=
"ORB")
566 END SUBROUTINE xas_tdp_core
575 SUBROUTINE xas_tdp_init(xas_tdp_env, xas_tdp_control, qs_env, rixs_env)
582 CHARACTER(LEN=default_string_length) :: kind_name
583 INTEGER :: at_ind, i, ispin, j, k, kind_ind, &
584 n_donor_states, n_kinds, nao, &
585 nat_of_kind, natom, nex_atoms, &
586 nex_kinds, nmatch, nspins
587 INTEGER,
DIMENSION(2) :: homo, n_mo, n_moloc
588 INTEGER,
DIMENSION(:),
POINTER :: ind_of_kind
589 LOGICAL :: do_os, do_rixs, do_uks, unique
591 REAL(
dp),
DIMENSION(:),
POINTER :: mo_evals
596 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_ks, matrix_s
603 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
608 NULLIFY (xas_tdp_section, at_kind_set, ind_of_kind, dft_control, qs_kind_set, tmp_basis)
609 NULLIFY (qs_loc_env, loc_section, mos, particle_set, mo_evals, cell)
610 NULLIFY (mo_coeff, matrix_ks, admm_env, dummy_section, matrix_p)
613 CALL get_qs_env(qs_env, dft_control=dft_control, do_rixs=do_rixs)
625 IF (dft_control%uks) xas_tdp_control%do_uks = .true.
626 IF (dft_control%roks) xas_tdp_control%do_roks = .true.
627 do_uks = xas_tdp_control%do_uks
628 do_os = do_uks .OR. xas_tdp_control%do_roks
631 IF (
PRESENT(rixs_env))
THEN
632 xas_tdp_env => rixs_env%core_state
641 nex_atoms =
SIZE(xas_tdp_control%list_ex_atoms)
643 ALLOCATE (xas_tdp_env%ex_atom_indices(nex_atoms))
644 ALLOCATE (xas_tdp_env%state_types(
SIZE(xas_tdp_control%state_types, 1), nex_atoms))
645 xas_tdp_env%ex_atom_indices = xas_tdp_control%list_ex_atoms
646 xas_tdp_env%state_types = xas_tdp_control%state_types
650 IF (any(xas_tdp_env%ex_atom_indices > natom))
THEN
651 cpabort(
"Invalid index for the ATOM_LIST keyword.")
655 ALLOCATE (xas_tdp_env%ex_kind_indices(nex_atoms))
656 xas_tdp_env%ex_kind_indices = 0
658 CALL get_qs_env(qs_env, particle_set=particle_set)
660 at_ind = xas_tdp_env%ex_atom_indices(i)
662 IF (all(abs(xas_tdp_env%ex_kind_indices - j) /= 0))
THEN
664 xas_tdp_env%ex_kind_indices(k) = j
669 CALL reallocate(xas_tdp_env%ex_kind_indices, 1, nex_kinds)
674 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=at_kind_set)
675 n_kinds =
SIZE(at_kind_set)
678 nex_kinds =
SIZE(xas_tdp_control%list_ex_kinds)
679 ALLOCATE (xas_tdp_env%ex_kind_indices(nex_kinds))
684 natom=nat_of_kind, kind_number=kind_ind)
685 IF (any(xas_tdp_control%list_ex_kinds == kind_name))
THEN
686 nex_atoms = nex_atoms + nat_of_kind
688 xas_tdp_env%ex_kind_indices(k) = kind_ind
692 ALLOCATE (xas_tdp_env%ex_atom_indices(nex_atoms))
693 ALLOCATE (xas_tdp_env%state_types(
SIZE(xas_tdp_control%state_types, 1), nex_atoms))
699 natom=nat_of_kind, atom_list=ind_of_kind)
701 IF (xas_tdp_control%list_ex_kinds(j) == kind_name)
THEN
702 xas_tdp_env%ex_atom_indices(nex_atoms + 1:nex_atoms + nat_of_kind) = ind_of_kind
703 DO k = 1,
SIZE(xas_tdp_control%state_types, 1)
704 xas_tdp_env%state_types(k, nex_atoms + 1:nex_atoms + nat_of_kind) = &
705 xas_tdp_control%state_types(k, j)
707 nex_atoms = nex_atoms + nat_of_kind
713 CALL set_xas_tdp_env(xas_tdp_env, nex_atoms=nex_atoms, nex_kinds=nex_kinds)
716 IF (nmatch /=
SIZE(xas_tdp_control%list_ex_kinds))
THEN
717 cpabort(
"Invalid kind(s) for the KIND_LIST keyword.")
723 CALL sort_unique(xas_tdp_env%ex_atom_indices, unique)
724 IF (.NOT. unique)
THEN
725 cpabort(
"Excited atoms not uniquely defined.")
730 IF (all(cell%perd == 0))
THEN
731 xas_tdp_control%is_periodic = .false.
732 ELSE IF (all(cell%perd == 1))
THEN
733 xas_tdp_control%is_periodic = .true.
735 cpabort(
"XAS TDP only implemented for full PBCs or non-PBCs")
740 ALLOCATE (xas_tdp_env%donor_states(n_donor_states))
741 DO i = 1, n_donor_states
746 IF (dft_control%do_admm)
THEN
747 CALL get_qs_env(qs_env, admm_env=admm_env, matrix_ks=matrix_ks)
749 DO ispin = 1, dft_control%nspins
755 IF (xas_tdp_control%eps_pgf > 0.0_dp)
THEN
756 CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set)
758 DO i = 1,
SIZE(qs_kind_set)
759 CALL get_qs_kind(qs_kind_set(i), basis_set=tmp_basis, basis_type=
"ORB")
761 CALL get_qs_kind(qs_kind_set(i), basis_set=tmp_basis, basis_type=
"RI_XAS")
769 CALL get_qs_env(qs_env, mos=mos, matrix_ks=matrix_ks)
770 nspins = 1;
IF (do_uks) nspins = 2
773 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, eigenvalues=mo_evals)
783 l_val=xas_tdp_control%do_loc)
786 xas_tdp_control%loc_subsection,
"PRINT")
788 ALLOCATE (xas_tdp_env%qs_loc_env)
790 qs_loc_env => xas_tdp_env%qs_loc_env
791 loc_section => xas_tdp_control%loc_subsection
794 CALL get_mo_set(mos(1), nmo=n_mo(1), homo=homo(1), nao=nao)
798 IF (do_os)
CALL get_mo_set(mos(2), nmo=n_mo(2), homo=homo(2))
799 IF (do_uks) nspins = 2
802 IF (xas_tdp_control%n_search < 0 .OR. xas_tdp_control%n_search > minval(homo))
THEN
803 xas_tdp_control%n_search = minval(homo)
806 nloc_xas=xas_tdp_control%n_search, spin_xas=1)
810 qs_loc_env%localized_wfn_control%nloc_states(2) = xas_tdp_control%n_search
811 qs_loc_env%localized_wfn_control%lu_bound_states(1, 2) = 1
812 qs_loc_env%localized_wfn_control%lu_bound_states(2, 2) = xas_tdp_control%n_search
816 qs_loc_env%localized_wfn_control%operator_type =
op_loc_berry
817 qs_loc_env%localized_wfn_control%max_iter = 25000
818 IF (.NOT. xas_tdp_control%do_loc)
THEN
819 qs_loc_env%localized_wfn_control%localization_method =
do_loc_none
821 n_moloc = qs_loc_env%localized_wfn_control%nloc_states
822 CALL set_loc_centers(qs_loc_env%localized_wfn_control, n_moloc, nspins)
825 qs_env, do_localize=.true.)
828 qs_env, do_localize=.true., myspin=1)
834 ALLOCATE (xas_tdp_env%mos_of_ex_atoms(xas_tdp_control%n_search, nex_atoms, nspins))
837 IF (do_os) nspins = 2
838 CALL get_qs_env(qs_env, matrix_s=matrix_s, mos=mos)
840 ALLOCATE (xas_tdp_env%q_projector(nspins))
841 ALLOCATE (xas_tdp_env%q_projector(1)%matrix)
842 CALL dbcsr_create(xas_tdp_env%q_projector(1)%matrix, name=
"Q PROJECTOR ALPHA", &
843 template=matrix_s(1)%matrix, matrix_type=dbcsr_type_no_symmetry)
845 ALLOCATE (xas_tdp_env%q_projector(2)%matrix)
846 CALL dbcsr_create(xas_tdp_env%q_projector(2)%matrix, name=
"Q PROJECTOR BETA", &
847 template=matrix_s(1)%matrix, matrix_type=dbcsr_type_no_symmetry)
851 CALL dbcsr_create(matrix_p, name=
"RHO_AO", template=matrix_s(1)%matrix, matrix_type=dbcsr_type_no_symmetry)
855 fact = -0.5_dp;
IF (do_os) fact = -1.0_dp
859 CALL dbcsr_multiply(
'N',
'N', fact, matrix_s(1)%matrix, matrix_p, 0.0_dp, &
860 xas_tdp_env%q_projector(1)%matrix, filter_eps=xas_tdp_control%eps_filter)
867 CALL dbcsr_multiply(
'N',
'N', fact, matrix_s(1)%matrix, matrix_p, 0.0_dp, &
868 xas_tdp_env%q_projector(2)%matrix, filter_eps=xas_tdp_control%eps_filter)
874 DEALLOCATE (matrix_p)
877 ALLOCATE (xas_tdp_env%dipmat(3))
879 ALLOCATE (xas_tdp_env%dipmat(i)%matrix)
880 CALL dbcsr_copy(matrix_tmp, matrix_s(1)%matrix, name=
"XAS TDP dipole matrix")
881 IF (xas_tdp_control%dipole_form ==
xas_dip_vel)
THEN
882 CALL dbcsr_create(xas_tdp_env%dipmat(i)%matrix, template=matrix_s(1)%matrix, &
883 matrix_type=dbcsr_type_antisymmetric)
886 CALL dbcsr_create(xas_tdp_env%dipmat(i)%matrix, template=matrix_s(1)%matrix, &
887 matrix_type=dbcsr_type_symmetric)
888 CALL dbcsr_copy(xas_tdp_env%dipmat(i)%matrix, matrix_tmp)
890 CALL dbcsr_set(xas_tdp_env%dipmat(i)%matrix, 0.0_dp)
895 IF (xas_tdp_control%do_quad)
THEN
896 ALLOCATE (xas_tdp_env%quadmat(6))
898 ALLOCATE (xas_tdp_env%quadmat(i)%matrix)
899 CALL dbcsr_copy(xas_tdp_env%quadmat(i)%matrix, matrix_s(1)%matrix, name=
"XAS TDP quadrupole matrix")
900 CALL dbcsr_set(xas_tdp_env%quadmat(i)%matrix, 0.0_dp)
905 IF (xas_tdp_control%dipole_form ==
xas_dip_vel)
THEN
911 IF (xas_tdp_control%do_soc .OR. xas_tdp_control%do_gw2x)
THEN
912 ALLOCATE (xas_tdp_env%orb_soc(3))
914 ALLOCATE (xas_tdp_env%orb_soc(i)%matrix)
919 CALL safety_check(xas_tdp_control, qs_env)
922 IF (xas_tdp_control%do_ot .OR. xas_tdp_control%do_gw2x)
THEN
923 CALL make_lumo_guess(xas_tdp_env, xas_tdp_control, qs_env)
936 SUBROUTINE get_ri_3c_batches(ex_atoms_of_kind, nbatch, batch_size, atoms_of_kind, xas_tdp_env)
938 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(INOUT) :: ex_atoms_of_kind
939 INTEGER,
INTENT(OUT) :: nbatch
940 INTEGER,
INTENT(IN) :: batch_size
941 INTEGER,
DIMENSION(:),
INTENT(IN) :: atoms_of_kind
944 INTEGER :: iat, iatom, nex_atom
949 DO iat = 1,
SIZE(atoms_of_kind)
950 iatom = atoms_of_kind(iat)
951 IF (.NOT. any(xas_tdp_env%ex_atom_indices == iatom)) cycle
952 nex_atom = nex_atom + 1
955 ALLOCATE (ex_atoms_of_kind(nex_atom))
957 DO iat = 1,
SIZE(atoms_of_kind)
958 iatom = atoms_of_kind(iat)
959 IF (.NOT. any(xas_tdp_env%ex_atom_indices == iatom)) cycle
960 nex_atom = nex_atom + 1
961 ex_atoms_of_kind(nex_atom) = iatom
966 CALL rng_stream%shuffle(ex_atoms_of_kind(1:nex_atom))
968 nbatch = nex_atom/batch_size
969 IF (nbatch*batch_size /= nex_atom) nbatch = nbatch + 1
971 END SUBROUTINE get_ri_3c_batches
978 SUBROUTINE safety_check(xas_tdp_control, qs_env)
986 IF (xas_tdp_control%is_periodic .AND. xas_tdp_control%do_hfx &
988 cpabort(
"XAS TDP with Coulomb operator for exact exchange only supports non-periodic BCs")
992 IF (xas_tdp_control%do_roks .OR. xas_tdp_control%do_uks)
THEN
994 IF (.NOT. (xas_tdp_control%do_spin_cons .OR. xas_tdp_control%do_spin_flip))
THEN
995 cpabort(
"Need spin-conserving and/or spin-flip excitations for open-shell systems")
998 IF (xas_tdp_control%do_singlet .OR. xas_tdp_control%do_triplet)
THEN
999 cpabort(
"Singlet/triplet excitations only for restricted closed-shell systems")
1002 IF (xas_tdp_control%do_soc .AND. .NOT. &
1003 (xas_tdp_control%do_spin_flip .AND. xas_tdp_control%do_spin_cons))
THEN
1005 cpabort(
"Both spin-conserving and spin-flip excitations are required for SOC")
1009 IF (.NOT. (xas_tdp_control%do_singlet .OR. xas_tdp_control%do_triplet))
THEN
1010 cpabort(
"Need singlet and/or triplet excitations for closed-shell systems")
1013 IF (xas_tdp_control%do_spin_cons .OR. xas_tdp_control%do_spin_flip)
THEN
1014 cpabort(
"Spin-conserving/spin-flip excitations only for open-shell systems")
1017 IF (xas_tdp_control%do_soc .AND. .NOT. &
1018 (xas_tdp_control%do_singlet .AND. xas_tdp_control%do_triplet))
THEN
1020 cpabort(
"Both singlet and triplet excitations are needed for SOC")
1025 IF (xas_tdp_control%do_soc .AND. xas_tdp_control%e_range > 0.0_dp)
THEN
1026 cpwarn(
"Using E_RANGE and SOC together may lead to crashes, use N_EXCITED for safety.")
1030 IF (.NOT. xas_tdp_control%tamm_dancoff)
THEN
1032 IF (xas_tdp_control%do_spin_flip)
THEN
1033 cpabort(
"Spin-flip kernel only implemented for Tamm-Dancoff approximation")
1036 IF (xas_tdp_control%do_ot)
THEN
1037 cpabort(
"OT diagonalization only available within the Tamm-Dancoff approximation")
1042 IF (xas_tdp_control%do_gw2x)
THEN
1043 IF (.NOT. xas_tdp_control%do_hfx)
THEN
1044 cpabort(
"GW2x requires the definition of the EXACT_EXCHANGE kernel")
1046 IF (.NOT. xas_tdp_control%do_loc)
THEN
1047 cpabort(
"GW2X requires the LOCALIZE keyword in DONOR_STATES")
1052 CALL get_qs_env(qs_env, dft_control=dft_control)
1053 IF (dft_control%do_admm)
THEN
1058 cpabort(
"XAS_TDP only compatible with ADMM purification NONE, CAUCHY_SUBSPACE and MO_DIAG")
1063 END SUBROUTINE safety_check
1071 SUBROUTINE print_info(ou, xas_tdp_control, qs_env)
1073 INTEGER,
INTENT(IN) :: ou
1077 REAL(kind=
dp),
PARAMETER :: eps_screen_thre = 1.0e-16_dp
1085 NULLIFY (input, kernel_section, dft_control, matrix_s)
1087 CALL get_qs_env(qs_env, input=input, dft_control=dft_control, matrix_s=matrix_s)
1095 IF (xas_tdp_control%do_uks)
THEN
1096 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1097 "XAS_TDP| Reference calculation: Unrestricted Kohn-Sham"
1098 ELSE IF (xas_tdp_control%do_roks)
THEN
1099 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1100 "XAS_TDP| Reference calculation: Restricted Open-Shell Kohn-Sham"
1102 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1103 "XAS_TDP| Reference calculation: Restricted Closed-Shell Kohn-Sham"
1107 IF (xas_tdp_control%tamm_dancoff)
THEN
1108 WRITE (unit=ou, fmt=
"(T3,A)") &
1109 "XAS_TDP| Tamm-Dancoff Approximation (TDA): On"
1111 WRITE (unit=ou, fmt=
"(T3,A)") &
1112 "XAS_TDP| Tamm-Dancoff Approximation (TDA): Off"
1116 IF (xas_tdp_control%dipole_form ==
xas_dip_vel)
THEN
1117 WRITE (unit=ou, fmt=
"(T3,A)") &
1118 "XAS_TDP| Transition Dipole Representation: VELOCITY"
1120 WRITE (unit=ou, fmt=
"(T3,A)") &
1121 "XAS_TDP| Transition Dipole Representation: LENGTH"
1125 IF (xas_tdp_control%do_quad)
THEN
1126 WRITE (unit=ou, fmt=
"(T3,A)") &
1127 "XAS_TDP| Transition Quadrupole: On"
1131 IF (xas_tdp_control%eps_pgf > 0.0_dp)
THEN
1132 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1133 "XAS_TDP| EPS_PGF_XAS: ", xas_tdp_control%eps_pgf
1135 WRITE (unit=ou, fmt=
"(T3,A,ES7.1,A)") &
1136 "XAS_TDP| EPS_PGF_XAS: ", dft_control%qs_control%eps_pgf_orb,
" (= EPS_PGF_ORB)"
1140 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1141 "XAS_TDP| EPS_FILTER: ", xas_tdp_control%eps_filter
1144 IF (xas_tdp_control%do_xc)
THEN
1145 WRITE (unit=ou, fmt=
"(T3,A)") &
1146 "XAS_TDP| Radial Grid(s) Info: Kind, na, nr"
1147 DO i = 1,
SIZE(xas_tdp_control%grid_info, 1)
1148 WRITE (unit=ou, fmt=
"(T3,A,A6,A,A,A,A)") &
1149 " ", trim(xas_tdp_control%grid_info(i, 1)),
", ", &
1150 trim(xas_tdp_control%grid_info(i, 2)),
", ", trim(xas_tdp_control%grid_info(i, 3))
1155 IF (.NOT. xas_tdp_control%do_coulomb)
THEN
1156 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1157 "XAS_TDP| No kernel (standard DFT)"
1161 IF (xas_tdp_control%do_xc)
THEN
1163 WRITE (unit=ou, fmt=
"(/,T3,A,F5.2,A)") &
1164 "XAS_TDP| RI Region's Radius: ", xas_tdp_control%ri_radius*
angstrom,
" Ang"
1166 WRITE (unit=ou, fmt=
"(T3,A,/)") &
1167 "XAS_TDP| XC Kernel Functional(s) used for the kernel:"
1169 IF (qs_env%do_rixs)
THEN
1174 CALL xc_write(ou, kernel_section, lsd=.true.)
1178 IF (xas_tdp_control%do_hfx)
THEN
1179 WRITE (unit=ou, fmt=
"(/,T3,A,/,/,T3,A,F5.3)") &
1180 "XAS_TDP| Exact Exchange Kernel: Yes ", &
1181 "EXACT_EXCHANGE| Scale: ", xas_tdp_control%sx
1183 WRITE (unit=ou, fmt=
"(T3,A)") &
1184 "EXACT_EXCHANGE| Potential : Coulomb"
1186 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,A)") &
1187 "EXACT_EXCHANGE| Potential: Truncated Coulomb", &
1188 "EXACT_EXCHANGE| Range: ", xas_tdp_control%x_potential%cutoff_radius*
angstrom,
", (Ang)", &
1189 "EXACT_EXCHANGE| T_C_G_DATA: ", trim(xas_tdp_control%x_potential%filename)
1191 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,F5.2,A,/,T3,A,ES7.1)") &
1192 "EXACT_EXCHANGE| Potential: Short Range", &
1193 "EXACT_EXCHANGE| Omega: ", xas_tdp_control%x_potential%omega,
", (1/a0)", &
1194 "EXACT_EXCHANGE| Effective Range: ", xas_tdp_control%x_potential%cutoff_radius*
angstrom,
", (Ang)", &
1195 "EXACT_EXCHANGE| EPS_RANGE: ", xas_tdp_control%eps_range
1197 IF (xas_tdp_control%eps_screen > eps_screen_thre)
THEN
1198 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1199 "EXACT_EXCHANGE| EPS_SCREENING: ", xas_tdp_control%eps_screen
1203 IF (xas_tdp_control%do_ri_metric)
THEN
1205 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1206 "EXACT_EXCHANGE| Using a RI metric"
1207 IF (xas_tdp_control%ri_m_potential%potential_type ==
do_potential_id)
THEN
1208 WRITE (unit=ou, fmt=
"(T3,A)") &
1209 "EXACT_EXCHANGE RI_METRIC| Potential : Overlap"
1211 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,A)") &
1212 "EXACT_EXCHANGE RI_METRIC| Potential: Truncated Coulomb", &
1213 "EXACT_EXCHANGE RI_METRIC| Range: ", xas_tdp_control%ri_m_potential%cutoff_radius &
1215 "EXACT_EXCHANGE RI_METRIC| T_C_G_DATA: ", trim(xas_tdp_control%ri_m_potential%filename)
1217 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,F5.2,A,/,T3,A,ES7.1)") &
1218 "EXACT_EXCHANGE RI_METRIC| Potential: Short Range", &
1219 "EXACT_EXCHANGE RI_METRIC| Omega: ", xas_tdp_control%ri_m_potential%omega,
", (1/a0)", &
1220 "EXACT_EXCHANGE RI_METRIC| Effective Range: ", &
1221 xas_tdp_control%ri_m_potential%cutoff_radius*
angstrom,
", (Ang)", &
1222 "EXACT_EXCHANGE RI_METRIC| EPS_RANGE: ", xas_tdp_control%eps_range
1226 WRITE (unit=ou, fmt=
"(/,T3,A,/)") &
1227 "XAS_TDP| Exact Exchange Kernel: No "
1231 WRITE (unit=ou, fmt=
"(/,T3,A,F5.2)") &
1232 "XAS_TDP| Overlap matrix occupation: ", occ
1235 IF (xas_tdp_control%do_gw2x)
THEN
1236 WRITE (unit=ou, fmt=
"(T3,A,/)") &
1237 "XAS_TDP| GW2X correction enabled"
1239 IF (xas_tdp_control%xps_only)
THEN
1240 WRITE (unit=ou, fmt=
"(T3,A)") &
1241 "GW2X| Only computing ionizations potentials for XPS"
1244 IF (xas_tdp_control%pseudo_canonical)
THEN
1245 WRITE (unit=ou, fmt=
"(T3,A)") &
1246 "GW2X| Using the pseudo-canonical scheme"
1248 WRITE (unit=ou, fmt=
"(T3,A)") &
1249 "GW2X| Using the GW2X* scheme"
1252 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1253 "GW2X| EPS_GW2X: ", xas_tdp_control%gw2x_eps
1255 WRITE (unit=ou, fmt=
"(T3,A,I5)") &
1256 "GW2X| contraction batch size: ", xas_tdp_control%batch_size
1258 IF ((int(xas_tdp_control%c_os) /= 1) .OR. (int(xas_tdp_control%c_ss) /= 1))
THEN
1259 WRITE (unit=ou, fmt=
"(T3,A,F7.4,/,T3,A,F7.4)") &
1260 "GW2X| Same-spin scaling factor: ", xas_tdp_control%c_ss, &
1261 "GW2X| Opposite-spin scaling factor: ", xas_tdp_control%c_os
1266 END SUBROUTINE print_info
1281 SUBROUTINE assign_mos_to_ex_atoms(xas_tdp_env, xas_tdp_control, qs_env)
1287 INTEGER :: at_index, iat, iat_memo, imo, ispin, &
1288 n_atoms, n_search, nex_atoms, nspins
1289 INTEGER,
DIMENSION(3) :: perd_init
1290 INTEGER,
DIMENSION(:, :, :),
POINTER :: mos_of_ex_atoms
1291 REAL(
dp) :: dist, dist_min
1292 REAL(
dp),
DIMENSION(3) :: at_pos, r_ac, wfn_center
1297 NULLIFY (localized_wfn_control, mos_of_ex_atoms, cell, particle_set)
1300 mos_of_ex_atoms => xas_tdp_env%mos_of_ex_atoms
1301 mos_of_ex_atoms(:, :, :) = -1
1302 n_search = xas_tdp_control%n_search
1303 nex_atoms = xas_tdp_env%nex_atoms
1304 localized_wfn_control => xas_tdp_env%qs_loc_env%localized_wfn_control
1305 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, cell=cell)
1306 n_atoms =
SIZE(particle_set)
1307 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1310 perd_init = cell%perd
1314 DO ispin = 1, nspins
1315 DO imo = 1, n_search
1317 wfn_center(1:3) = localized_wfn_control%centers_set(ispin)%array(1:3, imo)
1321 dist_min = 10000.0_dp
1323 at_pos = particle_set(iat)%r
1324 r_ac =
pbc(at_pos, wfn_center, cell)
1328 IF (dist < dist_min)
THEN
1335 IF (any(xas_tdp_env%ex_atom_indices == iat_memo))
THEN
1336 at_index =
locate(xas_tdp_env%ex_atom_indices, iat_memo)
1337 mos_of_ex_atoms(imo, at_index, ispin) = 1
1343 cell%perd = perd_init
1345 END SUBROUTINE assign_mos_to_ex_atoms
1357 SUBROUTINE reinit_qs_loc_env(qs_loc_env, n_loc_states, do_uks, qs_env)
1360 INTEGER,
INTENT(IN) :: n_loc_states
1361 LOGICAL,
INTENT(IN) :: do_uks
1364 INTEGER :: i, nspins
1373 loc_wfn_control => qs_loc_env%localized_wfn_control
1378 loc_wfn_control%nloc_states(:) = n_loc_states
1379 loc_wfn_control%eps_occ = 0.0_dp
1380 loc_wfn_control%lu_bound_states(1, :) = 1
1381 loc_wfn_control%lu_bound_states(2, :) = n_loc_states
1383 loc_wfn_control%do_homo = .true.
1384 ALLOCATE (loc_wfn_control%loc_states(n_loc_states, 2))
1385 DO i = 1, n_loc_states
1386 loc_wfn_control%loc_states(i, :) = i
1389 nspins = 1;
IF (do_uks) nspins = 2
1390 CALL set_loc_centers(loc_wfn_control, loc_wfn_control%nloc_states, nspins=nspins)
1393 CALL qs_loc_env_init(qs_loc_env, loc_wfn_control, qs_env, do_localize=.true.)
1395 CALL qs_loc_env_init(qs_loc_env, loc_wfn_control, qs_env, myspin=1, do_localize=.true.)
1398 END SUBROUTINE reinit_qs_loc_env
1408 SUBROUTINE diagonalize_assigned_mo_subset(xas_tdp_env, xas_tdp_control, qs_env)
1414 INTEGER :: i, iat, ilmo, ispin, nao, nlmo, nspins
1415 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: evals
1418 TYPE(
cp_fm_type) :: evecs, ks_fm, lmo_fm, work
1424 NULLIFY (mos, mo_coeff, matrix_ks, para_env, blacs_env, lmo_struct, ks_struct)
1427 CALL get_qs_env(qs_env, mos=mos, matrix_ks=matrix_ks, para_env=para_env, blacs_env=blacs_env)
1429 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1432 DO ispin = 1, nspins
1433 DO iat = 1, xas_tdp_env%nex_atoms
1436 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, nao=nao)
1439 nlmo = count(xas_tdp_env%mos_of_ex_atoms(:, iat, ispin) == 1)
1441 para_env=para_env, context=blacs_env)
1446 para_env=para_env, context=blacs_env)
1452 DO ilmo = 1, xas_tdp_control%n_search
1453 IF (xas_tdp_env%mos_of_ex_atoms(ilmo, iat, ispin) == -1) cycle
1458 s_firstcol=ilmo, t_firstrow=1, t_firstcol=i)
1464 CALL parallel_gemm(
'T',
'N', nlmo, nlmo, nao, 1.0_dp, lmo_fm, work, 0.0_dp, ks_fm)
1467 ALLOCATE (evals(nlmo))
1472 CALL parallel_gemm(
'N',
'N', nao, nlmo, nlmo, 1.0_dp, lmo_fm, evecs, 0.0_dp, work)
1476 DO ilmo = 1, xas_tdp_control%n_search
1477 IF (xas_tdp_env%mos_of_ex_atoms(ilmo, iat, ispin) == -1) cycle
1481 s_firstcol=i, t_firstrow=1, t_firstcol=ilmo)
1495 END SUBROUTINE diagonalize_assigned_mo_subset
1506 SUBROUTINE assign_mos_to_donor_state(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
1513 INTEGER :: at_index, i, iat, imo, ispin, l, my_mo, &
1514 n_search, n_states, nao, ndo_so, nj, &
1515 nsgf_kind, nsgf_sto, nspins, &
1517 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: my_mos
1518 INTEGER,
DIMENSION(2) :: next_best_overlap_ind
1519 INTEGER,
DIMENSION(4, 7) :: ne
1520 INTEGER,
DIMENSION(:),
POINTER :: first_sgf, lq, nq
1521 INTEGER,
DIMENSION(:, :, :),
POINTER :: mos_of_ex_atoms
1524 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) ::
diag, overlap, sto_overlap
1525 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: max_overlap
1526 REAL(
dp),
DIMENSION(2) :: next_best_overlap
1527 REAL(
dp),
DIMENSION(:),
POINTER :: mo_evals, zeta
1528 REAL(
dp),
DIMENSION(:, :),
POINTER :: overlap_matrix, tmp_coeff
1532 TYPE(
cp_fm_type),
POINTER :: gs_coeffs, mo_coeff
1538 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
1541 NULLIFY (sto_basis_set, sto_to_gto_basis_set, qs_kind_set, kind_basis_set, lq, nq, zeta)
1542 NULLIFY (overlap_matrix, mos, mo_coeff, mos_of_ex_atoms, tmp_coeff, first_sgf, particle_set)
1543 NULLIFY (mo_evals, matrix_ks, para_env, blacs_env)
1544 NULLIFY (eval_mat_struct, gs_struct, gs_coeffs)
1548 CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set, mos=mos, particle_set=particle_set, &
1549 matrix_ks=matrix_ks, para_env=para_env, blacs_env=blacs_env)
1551 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1562 ELSE IF (donor_state%state_type ==
xas_2s_type)
THEN
1566 ELSE IF (donor_state%state_type ==
xas_2p_type)
THEN
1571 cpabort(
"Procedure for required type not implemented")
1573 ALLOCATE (my_mos(n_states, nspins))
1574 ALLOCATE (max_overlap(n_states, nspins))
1577 CALL get_qs_kind(qs_kind_set(donor_state%kind_index), zeff=zeff)
1585 ne(l, i) =
ptable(zval)%e_conv(l - 1) - 2*nj*(i - l)
1586 ne(l, i) = max(ne(l, i), 0)
1587 ne(l, i) = min(ne(l, i), 2*nj)
1592 zeta(1) =
srules(zval, ne, nq(1), lq(1))
1599 DEALLOCATE (nq, lq, zeta)
1603 gto_basis_set=sto_to_gto_basis_set, &
1605 sto_to_gto_basis_set%norm_type = 2
1609 CALL get_qs_kind(qs_kind_set(donor_state%kind_index), basis_set=kind_basis_set)
1614 ALLOCATE (overlap_matrix(nsgf_sto, nsgf_kind))
1624 mos_of_ex_atoms => xas_tdp_env%mos_of_ex_atoms
1625 n_search = xas_tdp_control%n_search
1626 at_index = donor_state%at_index
1627 iat =
locate(xas_tdp_env%ex_atom_indices, at_index)
1628 ALLOCATE (first_sgf(
SIZE(particle_set)))
1629 CALL get_particle_set(particle_set=particle_set, qs_kind_set=qs_kind_set, first_sgf=first_sgf)
1630 ALLOCATE (tmp_coeff(nsgf_kind, 1))
1631 ALLOCATE (sto_overlap(nsgf_kind))
1632 ALLOCATE (overlap(n_search))
1634 next_best_overlap = 0.0_dp
1635 max_overlap = 0.0_dp
1637 DO ispin = 1, nspins
1639 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, nao=nao)
1643 DO imo = 1, n_search
1644 IF (mos_of_ex_atoms(imo, iat, ispin) > 0)
THEN
1646 sto_overlap = 0.0_dp
1650 CALL cp_fm_get_submatrix(fm=mo_coeff, target_m=tmp_coeff, start_row=first_sgf(at_index), &
1651 start_col=imo, n_rows=nsgf_kind, n_cols=1, transpose=.false.)
1654 CALL dgemm(
'N',
'N', nsgf_sto, 1, nsgf_kind, 1.0_dp, overlap_matrix, nsgf_sto, &
1655 tmp_coeff, nsgf_kind, 0.0_dp, sto_overlap, nsgf_sto)
1660 overlap(imo) = sum(abs(sto_overlap))
1667 my_mo = maxloc(overlap, 1)
1668 my_mos(i, ispin) = my_mo
1669 max_overlap(i, ispin) = maxval(overlap, 1)
1670 overlap(my_mo) = 0.0_dp
1673 next_best_overlap(ispin) = maxval(overlap, 1)
1674 next_best_overlap_ind(ispin) = maxloc(overlap, 1)
1682 DEALLOCATE (overlap_matrix, tmp_coeff)
1685 IF (all(my_mos > 0) .AND. all(my_mos <= n_search))
THEN
1687 ALLOCATE (donor_state%mo_indices(n_states, nspins))
1688 donor_state%mo_indices = my_mos
1689 donor_state%ndo_mo = n_states
1693 para_env=para_env, context=blacs_env)
1694 ALLOCATE (donor_state%gs_coeffs)
1697 IF (.NOT.
ASSOCIATED(xas_tdp_env%mo_coeff))
THEN
1698 ALLOCATE (xas_tdp_env%mo_coeff(nspins))
1701 DO ispin = 1, nspins
1702 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff)
1704 IF (.NOT.
ASSOCIATED(xas_tdp_env%mo_coeff(ispin)%local_data))
THEN
1707 matrix_struct=matrix_struct)
1708 CALL cp_fm_create(xas_tdp_env%mo_coeff(ispin), matrix_struct)
1709 CALL cp_fm_to_fm(mo_coeff, xas_tdp_env%mo_coeff(ispin))
1714 ncol=1, s_firstrow=1, s_firstcol=my_mos(i, ispin), &
1715 t_firstrow=1, t_firstcol=(ispin - 1)*n_states + i)
1718 gs_coeffs => donor_state%gs_coeffs
1721 ALLOCATE (donor_state%contract_coeffs(nsgf_kind, n_states*nspins))
1722 CALL cp_fm_get_submatrix(gs_coeffs, donor_state%contract_coeffs, start_row=first_sgf(at_index), &
1723 start_col=1, n_rows=nsgf_kind, n_cols=n_states*nspins)
1728 IF (.NOT. xas_tdp_control%do_loc .AND. .NOT. xas_tdp_control%do_roks)
THEN
1729 IF (output_unit > 0)
THEN
1730 WRITE (unit=output_unit, fmt=
"(T5,A,/,T5,A,/,T5,A)") &
1731 "The following canonical MO(s) have been associated with the donor state(s)", &
1732 "based on the overlap with the components of a minimal STO basis: ", &
1733 " Spin MO index overlap(sum)"
1736 ALLOCATE (donor_state%energy_evals(n_states, nspins))
1737 donor_state%energy_evals = 0.0_dp
1740 DO ispin = 1, nspins
1741 CALL get_mo_set(mos(ispin), eigenvalues=mo_evals)
1743 donor_state%energy_evals(i, ispin) = mo_evals(my_mos(i, ispin))
1745 IF (output_unit > 0)
THEN
1746 WRITE (unit=output_unit, fmt=
"(T46,I4,I11,F17.5)") &
1747 ispin, my_mos(i, ispin), max_overlap(i, ispin)
1755 IF (output_unit > 0)
THEN
1756 WRITE (unit=output_unit, fmt=
"(T5,A,/,T5,A,/,T5,A)") &
1757 "The following localized MO(s) have been associated with the donor state(s)", &
1758 "based on the overlap with the components of a minimal STO basis: ", &
1759 " Spin MO index overlap(sum)"
1763 DO ispin = 1, nspins
1767 IF (output_unit > 0)
THEN
1768 WRITE (unit=output_unit, fmt=
"(T46,I4,I11,F17.5)") &
1769 ispin, my_mos(i, ispin), max_overlap(i, ispin)
1777 ndo_so = nspins*n_states
1780 para_env=para_env, context=blacs_env)
1782 ALLOCATE (
diag(ndo_so))
1784 IF (.NOT. xas_tdp_control%do_roks)
THEN
1786 ALLOCATE (donor_state%energy_evals(n_states, nspins))
1787 donor_state%energy_evals = 0.0_dp
1790 DO ispin = 1, nspins
1792 CALL parallel_gemm(
'T',
'N', ndo_so, ndo_so, nao, 1.0_dp, gs_coeffs, work_mat, 0.0_dp, eval_mat)
1796 donor_state%energy_evals(:, ispin) =
diag((ispin - 1)*n_states + 1:ispin*n_states)
1802 ALLOCATE (donor_state%energy_evals(n_states, 2))
1803 donor_state%energy_evals = 0.0_dp
1808 CALL parallel_gemm(
'T',
'N', ndo_so, ndo_so, nao, 1.0_dp, gs_coeffs, work_mat, 0.0_dp, eval_mat)
1811 donor_state%energy_evals(:, ispin) =
diag(:)
1826 ALLOCATE (donor_state%gw2x_evals(
SIZE(donor_state%energy_evals, 1),
SIZE(donor_state%energy_evals, 2)))
1827 donor_state%gw2x_evals(:, :) = donor_state%energy_evals(:, :)
1831 DEALLOCATE (first_sgf)
1833 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T5,A)")
" "
1835 DO ispin = 1, nspins
1836 IF (output_unit > 0)
THEN
1837 WRITE (unit=output_unit, fmt=
"(T5,A,I1,A,F7.5,A,I4)") &
1838 "The next best overlap for spin ", ispin,
" is ", next_best_overlap(ispin), &
1839 " for MO with index ", next_best_overlap_ind(ispin)
1842 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T5,A)")
" "
1845 cpabort(
"A core donor state could not be assigned MO(s). Increasing NSEARCH might help.")
1848 END SUBROUTINE assign_mos_to_donor_state
1858 SUBROUTINE find_mo_centers(xas_tdp_env, xas_tdp_control, qs_env)
1864 INTEGER :: dim_op, i, ispin, j, n_centers, nao, &
1866 REAL(
dp),
DIMENSION(6) :: weights
1871 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:, :) :: zij_fm_set
1872 TYPE(
cp_fm_type),
DIMENSION(:),
POINTER :: moloc_coeff
1874 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: op_sm_set
1879 NULLIFY (qs_loc_env, cell, print_loc_section, op_sm_set, moloc_coeff, vectors)
1880 NULLIFY (tmp_fm_struct, para_env, blacs_env, prog_run_info)
1883 print_loc_section => xas_tdp_control%print_loc_subsection
1884 n_centers = xas_tdp_control%n_search
1885 CALL get_qs_env(qs_env=qs_env, para_env=para_env, blacs_env=blacs_env, cell=cell)
1893 CALL reinit_qs_loc_env(xas_tdp_env%qs_loc_env, n_centers, xas_tdp_control%do_uks, qs_env)
1894 qs_loc_env => xas_tdp_env%qs_loc_env
1897 CALL get_qs_loc_env(qs_loc_env=qs_loc_env, weights=weights, op_sm_set=op_sm_set, &
1898 moloc_coeff=moloc_coeff)
1901 vectors => moloc_coeff(1)
1906 ncol_global=n_centers, nrow_global=n_centers)
1908 IF (cell%orthorhombic)
THEN
1913 ALLOCATE (zij_fm_set(2, dim_op))
1921 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1923 DO ispin = 1, nspins
1925 vectors => moloc_coeff(ispin)
1930 CALL parallel_gemm(
"T",
"N", n_centers, n_centers, nao, 1.0_dp, vectors, opvec, 0.0_dp, &
1937 cell=cell, weights=weights, ispin=ispin, &
1938 print_loc_section=print_loc_section, only_initial_out=.true.)
1947 qs_loc_env%do_localize = xas_tdp_control%do_loc
1949 END SUBROUTINE find_mo_centers
1958 SUBROUTINE print_checks(xas_tdp_env, xas_tdp_control, qs_env)
1964 CHARACTER(LEN=default_string_length) :: kind_name
1965 INTEGER :: current_state_index, iat, iatom, ikind, &
1966 istate, output_unit, tmp_index
1967 INTEGER,
DIMENSION(:),
POINTER :: atoms_of_kind
1971 NULLIFY (atomic_kind_set, atoms_of_kind, current_state)
1975 IF (output_unit > 0)
THEN
1976 WRITE (output_unit,
"(/,T3,A,/,T3,A,/,T3,A)") &
1977 "# Check the donor states for their quality. They need to have a well defined type ", &
1978 " (1s, 2s, etc) which is indicated by the overlap. They also need to be localized, ", &
1979 " for which the Mulliken population analysis is one indicator (must be close to 1.0)"
1983 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
1984 current_state_index = 1
1987 DO ikind = 1,
SIZE(atomic_kind_set)
1989 CALL get_atomic_kind(atomic_kind=atomic_kind_set(ikind), name=kind_name, &
1990 atom_list=atoms_of_kind)
1992 IF (.NOT. any(xas_tdp_env%ex_kind_indices == ikind)) cycle
1995 DO iat = 1,
SIZE(atoms_of_kind)
1996 iatom = atoms_of_kind(iat)
1998 IF (.NOT. any(xas_tdp_env%ex_atom_indices == iatom)) cycle
1999 tmp_index =
locate(xas_tdp_env%ex_atom_indices, iatom)
2002 DO istate = 1,
SIZE(xas_tdp_env%state_types, 1)
2004 IF (xas_tdp_env%state_types(istate, tmp_index) ==
xas_not_excited) cycle
2006 current_state => xas_tdp_env%donor_states(current_state_index)
2008 at_symbol=kind_name, kind_index=ikind, &
2009 state_type=xas_tdp_env%state_types(istate, tmp_index))
2011 IF (output_unit > 0)
THEN
2012 WRITE (output_unit,
"(/,T4,A,A2,A,I4,A,A,A)") &
2013 "-Donor state of type ", xas_tdp_env%state_type_char(current_state%state_type), &
2014 " for atom", current_state%at_index,
" of kind ", trim(current_state%at_symbol),
":"
2018 CALL assign_mos_to_donor_state(current_state, xas_tdp_env, xas_tdp_control, qs_env)
2019 CALL perform_mulliken_on_donor_state(current_state, qs_env)
2021 current_state_index = current_state_index + 1
2022 NULLIFY (current_state)
2028 IF (output_unit > 0)
THEN
2029 WRITE (output_unit,
"(/,T5,A)") &
2030 "Use LOCALIZE and/or increase N_SEARCH for better results, if so required."
2033 END SUBROUTINE print_checks
2043 SUBROUTINE compute_lenrep_multipole(iatom, xas_tdp_env, xas_tdp_control, qs_env)
2045 INTEGER,
INTENT(IN) :: iatom
2051 REAL(
dp),
DIMENSION(3) :: rc
2055 NULLIFY (work, particle_set)
2057 CALL get_qs_env(qs_env, particle_set=particle_set)
2058 rc = particle_set(iatom)%r
2061 IF (xas_tdp_control%dipole_form ==
xas_dip_len)
THEN
2063 CALL dbcsr_set(xas_tdp_env%dipmat(i)%matrix, 0.0_dp)
2064 work(i)%matrix => xas_tdp_env%dipmat(i)%matrix
2067 all_images=.true., minimum_image=.true.)
2069 IF (xas_tdp_control%do_quad)
THEN
2071 CALL dbcsr_set(xas_tdp_env%quadmat(i)%matrix, 0.0_dp)
2072 work(3 + i)%matrix => xas_tdp_env%quadmat(i)%matrix
2075 all_images=.true., minimum_image=.true., first_component=4)
2079 END SUBROUTINE compute_lenrep_multipole
2093 SUBROUTINE compute_dipole_fosc(donor_state, xas_tdp_control, xas_tdp_env)
2099 CHARACTER(len=*),
PARAMETER :: routinen =
'compute_dipole_fosc'
2101 INTEGER :: handle, iosc, j, nao, ndo_mo, ndo_so, &
2103 LOGICAL :: do_sc, do_sg
2104 REAL(
dp) :: alpha_xyz, beta_xyz, osc_xyz, pref
2105 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: alpha_contr, beta_contr, tot_contr
2106 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: dip_block
2107 REAL(
dp),
DIMENSION(:),
POINTER :: lr_evals
2108 REAL(
dp),
DIMENSION(:, :),
POINTER :: alpha_osc, beta_osc, osc_str
2116 NULLIFY (dipmat, col_struct, mat_struct, para_env, blacs_env, lr_coeffs)
2117 NULLIFY (lr_evals, osc_str, alpha_osc, beta_osc)
2119 CALL timeset(routinen, handle)
2122 do_sc = xas_tdp_control%do_spin_cons
2123 do_sg = xas_tdp_control%do_singlet
2126 lr_evals => donor_state%sc_evals
2127 lr_coeffs => donor_state%sc_coeffs
2128 ELSE IF (do_sg)
THEN
2130 lr_evals => donor_state%sg_evals
2131 lr_coeffs => donor_state%sg_coeffs
2133 cpabort(
"Dipole oscilaltor strength only for singlets and spin-conserving excitations.")
2135 ndo_mo = donor_state%ndo_mo
2136 ndo_so = ndo_mo*nspins
2137 ngs = ndo_so;
IF (xas_tdp_control%do_roks) ngs = ndo_mo
2138 nosc =
SIZE(lr_evals)
2139 ALLOCATE (donor_state%osc_str(nosc, 4), donor_state%alpha_osc(nosc, 4), donor_state%beta_osc(nosc, 4))
2140 osc_str => donor_state%osc_str
2141 alpha_osc => donor_state%alpha_osc
2142 beta_osc => donor_state%beta_osc
2146 dipmat => xas_tdp_env%dipmat
2149 CALL cp_fm_get_info(donor_state%gs_coeffs, matrix_struct=col_struct, para_env=para_env, &
2150 context=blacs_env, nrow_global=nao)
2152 nrow_global=ndo_so*nosc, ncol_global=ngs)
2156 ALLOCATE (tot_contr(ndo_mo), dip_block(ndo_so, ngs), alpha_contr(ndo_mo), beta_contr(ndo_mo))
2157 pref = 2.0_dp;
IF (do_sc) pref = 1.0_dp
2165 CALL parallel_gemm(
'T',
'N', ndo_so*nosc, ngs, nao, 1.0_dp, lr_coeffs, col_work, 0.0_dp, mat_work)
2171 CALL cp_fm_get_submatrix(fm=mat_work, target_m=dip_block, start_row=(iosc - 1)*ndo_so + 1, &
2172 start_col=1, n_rows=ndo_so, n_cols=ngs)
2175 ELSE IF (do_sc .AND. xas_tdp_control%do_uks)
THEN
2176 alpha_contr(:) =
get_diag(dip_block(1:ndo_mo, 1:ndo_mo))
2177 beta_contr(:) =
get_diag(dip_block(ndo_mo + 1:ndo_so, ndo_mo + 1:ndo_so))
2178 tot_contr(:) = alpha_contr(:) + beta_contr(:)
2181 alpha_contr(:) =
get_diag(dip_block(1:ndo_mo, :))
2182 beta_contr(:) =
get_diag(dip_block(ndo_mo + 1:ndo_so, :))
2183 tot_contr(:) = alpha_contr(:) + beta_contr(:)
2186 osc_xyz = sum(tot_contr)**2
2187 alpha_xyz = sum(alpha_contr)**2
2188 beta_xyz = sum(beta_contr)**2
2190 alpha_osc(iosc, 4) = alpha_osc(iosc, 4) + alpha_xyz
2191 alpha_osc(iosc, j) = alpha_xyz
2193 beta_osc(iosc, 4) = beta_osc(iosc, 4) + beta_xyz
2194 beta_osc(iosc, j) = beta_xyz
2196 osc_str(iosc, 4) = osc_str(iosc, 4) + osc_xyz
2197 osc_str(iosc, j) = osc_xyz
2204 IF (xas_tdp_control%dipole_form ==
xas_dip_len)
THEN
2205 osc_str(:, j) = pref*2.0_dp/3.0_dp*lr_evals(:)*osc_str(:, j)
2206 alpha_osc(:, j) = pref*2.0_dp/3.0_dp*lr_evals(:)*alpha_osc(:, j)
2207 beta_osc(:, j) = pref*2.0_dp/3.0_dp*lr_evals(:)*beta_osc(:, j)
2209 osc_str(:, j) = pref*2.0_dp/3.0_dp/lr_evals(:)*osc_str(:, j)
2210 alpha_osc(:, j) = pref*2.0_dp/3.0_dp/lr_evals(:)*alpha_osc(:, j)
2211 beta_osc(:, j) = pref*2.0_dp/3.0_dp/lr_evals(:)*beta_osc(:, j)
2220 CALL timestop(handle)
2222 END SUBROUTINE compute_dipole_fosc
2232 SUBROUTINE compute_quadrupole_fosc(donor_state, xas_tdp_control, xas_tdp_env)
2238 CHARACTER(len=*),
PARAMETER :: routinen =
'compute_quadrupole_fosc'
2240 INTEGER :: handle, iosc, j, nao, ndo_mo, ndo_so, &
2242 LOGICAL :: do_sc, do_sg
2244 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: tot_contr, trace
2245 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: quad_block
2246 REAL(
dp),
DIMENSION(:),
POINTER :: lr_evals, osc_str
2254 NULLIFY (lr_evals, osc_str, lr_coeffs, col_struct, mat_struct, para_env)
2257 CALL timeset(routinen, handle)
2260 do_sc = xas_tdp_control%do_spin_cons
2261 do_sg = xas_tdp_control%do_singlet
2264 lr_evals => donor_state%sc_evals
2265 lr_coeffs => donor_state%sc_coeffs
2266 ELSE IF (do_sg)
THEN
2268 lr_evals => donor_state%sg_evals
2269 lr_coeffs => donor_state%sg_coeffs
2271 cpabort(
"Quadrupole oscillator strengths only for singlet and spin-conserving excitations")
2273 ndo_mo = donor_state%ndo_mo
2274 ndo_so = ndo_mo*nspins
2275 ngs = ndo_so;
IF (xas_tdp_control%do_roks) ngs = ndo_mo
2276 nosc =
SIZE(lr_evals)
2277 ALLOCATE (donor_state%quad_osc_str(nosc))
2278 osc_str => donor_state%quad_osc_str
2280 quadmat => xas_tdp_env%quadmat
2283 CALL cp_fm_get_info(donor_state%gs_coeffs, matrix_struct=col_struct, para_env=para_env, &
2284 context=blacs_env, nrow_global=nao)
2286 nrow_global=ndo_so*nosc, ncol_global=ngs)
2290 ALLOCATE (quad_block(ndo_so, ngs), tot_contr(ndo_mo))
2291 pref = 2.0_dp;
IF (do_sc) pref = 1.0_dp
2292 ALLOCATE (trace(nosc))
2301 CALL parallel_gemm(
'T',
'N', ndo_so*nosc, ngs, nao, 1.0_dp, lr_coeffs, col_work, 0.0_dp, mat_work)
2307 CALL cp_fm_get_submatrix(fm=mat_work, target_m=quad_block, start_row=(iosc - 1)*ndo_so + 1, &
2308 start_col=1, n_rows=ndo_so, n_cols=ngs)
2311 tot_contr(:) =
get_diag(quad_block)
2312 ELSE IF (do_sc .AND. xas_tdp_control%do_uks)
THEN
2313 tot_contr(:) =
get_diag(quad_block(1:ndo_mo, 1:ndo_mo))
2314 tot_contr(:) = tot_contr(:) +
get_diag(quad_block(ndo_mo + 1:ndo_so, ndo_mo + 1:ndo_so))
2317 tot_contr(:) =
get_diag(quad_block(1:ndo_mo, :))
2318 tot_contr(:) = tot_contr(:) +
get_diag(quad_block(ndo_mo + 1:ndo_so, :))
2322 IF (j == 1 .OR. j == 4 .OR. j == 6)
THEN
2323 osc_str(iosc) = osc_str(iosc) + sum(tot_contr)**2
2324 trace(iosc) = trace(iosc) + sum(tot_contr)
2328 osc_str(iosc) = osc_str(iosc) + 2.0_dp*sum(tot_contr)**2
2335 osc_str(:) = pref*1._dp/20._dp*
a_fine**2*lr_evals(:)**3*(osc_str(:) - 1._dp/3._dp*trace(:)**2)
2342 CALL timestop(handle)
2344 END SUBROUTINE compute_quadrupole_fosc
2353 SUBROUTINE write_mos_to_ex_atoms_association(xas_tdp_env, xas_tdp_control, qs_env)
2359 CHARACTER(LEN=default_string_length) :: kind_name
2360 INTEGER :: at_index, imo, ispin, nmo, nspins, &
2361 output_unit, tmp_index
2362 INTEGER,
DIMENSION(3) :: perd_init
2363 INTEGER,
DIMENSION(:),
POINTER :: ex_atom_indices
2364 INTEGER,
DIMENSION(:, :, :),
POINTER :: mos_of_ex_atoms
2365 REAL(
dp) :: dist, mo_spread
2366 REAL(
dp),
DIMENSION(3) :: at_pos, r_ac, wfn_center
2370 NULLIFY (cell, particle_set, mos_of_ex_atoms, ex_atom_indices)
2374 IF (output_unit > 0)
THEN
2375 WRITE (unit=output_unit, fmt=
"(/,T3,A,/,T3,A,/,T3,A)") &
2376 " Associated Associated Distance to MO spread (Ang^2)", &
2377 "Spin MO index atom index atom kind MO center (Ang) -w_i ln(|z_ij|^2)", &
2378 "---------------------------------------------------------------------------------"
2382 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
2383 mos_of_ex_atoms => xas_tdp_env%mos_of_ex_atoms
2384 ex_atom_indices => xas_tdp_env%ex_atom_indices
2385 nmo = xas_tdp_control%n_search
2386 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, cell=cell)
2389 perd_init = cell%perd
2394 DO ispin = 1, nspins
2397 IF (any(mos_of_ex_atoms(imo, :, ispin) == 1))
THEN
2398 tmp_index = maxloc(mos_of_ex_atoms(imo, :, ispin), 1)
2399 at_index = ex_atom_indices(tmp_index)
2400 kind_name = particle_set(at_index)%atomic_kind%name
2402 at_pos = particle_set(at_index)%r
2403 wfn_center = xas_tdp_env%qs_loc_env%localized_wfn_control%centers_set(ispin)%array(1:3, imo)
2404 r_ac =
pbc(at_pos, wfn_center, cell)
2409 mo_spread = xas_tdp_env%qs_loc_env%localized_wfn_control%centers_set(ispin)%array(4, imo)
2412 IF (output_unit > 0)
THEN
2413 WRITE (unit=output_unit, fmt=
"(T3,I4,I10,I14,A14,ES19.3,ES20.3)") &
2414 ispin, imo, at_index, trim(kind_name), dist, mo_spread
2421 IF (output_unit > 0)
THEN
2422 WRITE (unit=output_unit, fmt=
"(T3,A,/)") &
2423 "---------------------------------------------------------------------------------"
2427 cell%perd = perd_init
2429 END SUBROUTINE write_mos_to_ex_atoms_association
2440 SUBROUTINE perform_mulliken_on_donor_state(donor_state, qs_env)
2444 INTEGER :: at_index, i, ispin, nao, natom, ndo_mo, &
2445 ndo_so, nsgf, nspins, output_unit
2446 INTEGER,
DIMENSION(:),
POINTER :: first_sgf, last_sgf
2447 INTEGER,
DIMENSION(:, :),
POINTER :: mo_indices
2448 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: mul_pop, pop_mat
2449 REAL(
dp),
DIMENSION(:, :),
POINTER :: work_array
2457 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2459 NULLIFY (mo_indices, qs_kind_set, particle_set, first_sgf, work_array)
2460 NULLIFY (matrix_s, para_env, blacs_env, col_vect_struct, last_sgf)
2463 at_index = donor_state%at_index
2464 mo_indices => donor_state%mo_indices
2465 ndo_mo = donor_state%ndo_mo
2466 gs_coeffs => donor_state%gs_coeffs
2468 nspins = 1;
IF (
SIZE(mo_indices, 2) == 2) nspins = 2
2469 ndo_so = ndo_mo*nspins
2470 ALLOCATE (mul_pop(ndo_mo, nspins))
2473 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, qs_kind_set=qs_kind_set, &
2474 para_env=para_env, blacs_env=blacs_env, matrix_s=matrix_s)
2475 CALL cp_fm_get_info(gs_coeffs, nrow_global=nao, matrix_struct=col_vect_struct)
2477 natom =
SIZE(particle_set, 1)
2478 ALLOCATE (first_sgf(natom))
2479 ALLOCATE (last_sgf(natom))
2481 CALL get_particle_set(particle_set, qs_kind_set, first_sgf=first_sgf, last_sgf=last_sgf)
2482 nsgf = last_sgf(at_index) - first_sgf(at_index) + 1
2490 ALLOCATE (work_array(nsgf, ndo_so))
2491 ALLOCATE (pop_mat(ndo_so, ndo_so))
2493 CALL cp_fm_get_submatrix(fm=work_vect, target_m=work_array, start_row=first_sgf(at_index), &
2494 start_col=1, n_rows=nsgf, n_cols=ndo_so, transpose=.false.)
2496 CALL dgemm(
'T',
'N', ndo_so, ndo_so, nsgf, 1.0_dp, donor_state%contract_coeffs, nsgf, &
2497 work_array, nsgf, 0.0_dp, pop_mat, ndo_so)
2500 DO ispin = 1, nspins
2502 mul_pop(i, ispin) = pop_mat((ispin - 1)*ndo_mo + i, (ispin - 1)*ndo_mo + i)
2507 IF (output_unit > 0)
THEN
2508 WRITE (unit=output_unit, fmt=
"(T5,A,/,T5,A)") &
2509 "Mulliken population analysis retricted to the associated MO(s) yields: ", &
2510 " Spin MO index charge"
2511 DO ispin = 1, nspins
2513 WRITE (unit=output_unit, fmt=
"(T51,I4,I10,F11.3)") &
2514 ispin, mo_indices(i, ispin), mul_pop(i, ispin)
2520 DEALLOCATE (first_sgf, last_sgf, work_array)
2523 END SUBROUTINE perform_mulliken_on_donor_state
2533 SUBROUTINE xas_tdp_post(ex_type, donor_state, xas_tdp_env, xas_tdp_section, qs_env)
2535 INTEGER,
INTENT(IN) :: ex_type
2541 CHARACTER(len=*),
PARAMETER :: routinen =
'xas_tdp_post'
2543 CHARACTER(len=default_string_length) :: domo, domon, excite, pos, xas_mittle
2544 INTEGER :: ex_state_idx, handle, ic, ido_mo, imo, irep, ispin, n_dependent, n_rep, nao, &
2545 ncubes, ndo_mo, ndo_so, nlumo, nmo, nspins, output_unit
2546 INTEGER,
DIMENSION(:),
POINTER :: bounds,
list, state_list
2547 LOGICAL :: append_cube, do_cubes, do_pdos, &
2549 REAL(
dp),
DIMENSION(:),
POINTER :: lr_evals
2550 REAL(
dp),
DIMENSION(:, :),
POINTER :: centers
2562 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2565 NULLIFY (atomic_kind_set, particle_set, qs_kind_set, mo_set, lr_evals, lr_coeffs)
2566 NULLIFY (mo_struct, para_env, blacs_env, fm_struct, matrix_s, print_key, logger)
2567 NULLIFY (bounds, state_list,
list, mos)
2571 do_pdos = .false.; do_cubes = .false.; do_wfn_restart = .false.
2574 "PRINT%PDOS"),
cp_p_file)) do_pdos = .true.
2577 "PRINT%CUBES"),
cp_p_file)) do_cubes = .true.
2580 "PRINT%RESTART_WFN"),
cp_p_file)) do_wfn_restart = .true.
2582 IF (.NOT. (do_pdos .OR. do_cubes .OR. do_wfn_restart))
RETURN
2584 CALL timeset(routinen, handle)
2587 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, particle_set=particle_set, &
2588 qs_kind_set=qs_kind_set, para_env=para_env, blacs_env=blacs_env, &
2589 matrix_s=matrix_s, mos=mos)
2591 SELECT CASE (ex_type)
2593 lr_evals => donor_state%sc_evals
2594 lr_coeffs => donor_state%sc_coeffs
2598 lr_evals => donor_state%sf_evals
2599 lr_coeffs => donor_state%sf_coeffs
2603 lr_evals => donor_state%sg_evals
2604 lr_coeffs => donor_state%sg_coeffs
2608 lr_evals => donor_state%tp_evals
2609 lr_coeffs => donor_state%tp_coeffs
2614 SELECT CASE (donor_state%state_type)
2623 ndo_mo = donor_state%ndo_mo
2624 ndo_so = ndo_mo*nspins
2625 nmo =
SIZE(lr_evals)
2629 nrow_global=nao, ncol_global=nmo)
2633 IF (do_wfn_restart)
THEN
2636 IF (.NOT. (nspins == 1 .AND. donor_state%state_type ==
xas_1s_type))
THEN
2637 cpabort(
"RESTART.wfn file only available for RKS K-edge XAS spectroscopy")
2640 CALL section_vals_val_get(xas_tdp_section,
"PRINT%RESTART_WFN%EXCITED_STATE_INDEX", n_rep_val=n_rep)
2644 i_rep_val=irep, i_val=ex_state_idx)
2645 cpassert(ex_state_idx <=
SIZE(lr_evals))
2651 IF (
SIZE(mos) == 1)
THEN
2652 restart_mos(ispin)%occupation_numbers = mos(1)%occupation_numbers/2
2656 CALL cp_fm_to_fm_submat(msource=lr_coeffs, mtarget=restart_mos(1)%mo_coeff, nrow=nao, &
2657 ncol=1, s_firstrow=1, s_firstcol=ex_state_idx, t_firstrow=1, &
2658 t_firstcol=donor_state%mo_indices(1, 1))
2660 xas_mittle =
'xasat'//trim(adjustl(
cp_to_string(donor_state%at_index)))//
'_'//trim(domo)// &
2661 '_'//trim(excite)//
'_idx'//trim(adjustl(
cp_to_string(ex_state_idx)))
2663 extension=
".wfn", file_status=
"REPLACE", &
2664 file_action=
"WRITE", file_form=
"UNFORMATTED", &
2665 middle_name=xas_mittle)
2668 qs_kind_set=qs_kind_set, ires=output_unit)
2683 IF (.NOT.
ASSOCIATED(xas_tdp_env%matrix_shalf) .AND. do_pdos)
THEN
2685 nrow_global=nao, ncol_global=nao)
2686 ALLOCATE (xas_tdp_env%matrix_shalf)
2691 CALL cp_fm_power(xas_tdp_env%matrix_shalf, work_fm, 0.5_dp, epsilon(0.0_dp), n_dependent)
2699 IF (output_unit > 0)
THEN
2700 WRITE (unit=output_unit, fmt=
"(/,T5,A,/,T5,A,/,T5,A)") &
2701 "Computing the PDOS of linear-response orbitals for spectral features analysis", &
2702 "Note: using standard PDOS routines => ignore mentions of KS states and MO ", &
2703 " occupation numbers. Eigenvalues in *.pdos files are excitations energies."
2708 IF (nlumo /= 0)
THEN
2709 cpwarn(
"NLUMO is irrelevant for XAS_TDP PDOS. It was overwritten to 0.")
2720 ncubes = bounds(2) - bounds(1) + 1
2721 IF (ncubes > 0)
THEN
2722 ALLOCATE (state_list(ncubes))
2724 state_list(ic) = bounds(1) + ic - 1
2728 IF (.NOT.
ASSOCIATED(state_list))
THEN
2735 IF (
ASSOCIATED(
list))
THEN
2737 DO ic = 1,
SIZE(
list)
2738 state_list(ncubes + ic) =
list(ic)
2740 ncubes = ncubes +
SIZE(
list)
2745 IF (.NOT.
ASSOCIATED(state_list))
THEN
2747 ALLOCATE (state_list(1))
2753 IF (append_cube) pos =
"APPEND"
2755 ALLOCATE (centers(6, ncubes))
2761 DO ido_mo = 1, ndo_mo
2762 DO ispin = 1, nspins
2766 CALL allocate_mo_set(mo_set, nao=nao, nmo=nmo, nelectron=nmo, n_el_f=real(nmo,
dp), &
2767 maxocc=1.0_dp, flexible_electron_count=0.0_dp)
2768 CALL init_mo_set(mo_set, fm_ref=mo_coeff, name=
"PDOS XAS_TDP MOs")
2769 mo_set%eigenvalues(:) = lr_evals(:)
2772 IF (nspins == 1 .AND. ndo_mo == 1)
THEN
2777 nrow=nao, ncol=1, s_firstrow=1, &
2778 s_firstcol=(imo - 1)*ndo_so + (ispin - 1)*ndo_mo + ido_mo, &
2779 t_firstrow=1, t_firstcol=imo)
2786 xas_mittle =
'xasat'//trim(adjustl(
cp_to_string(donor_state%at_index)))//
'_'// &
2787 trim(domon)//
'_'//trim(excite)
2791 qs_env, xas_tdp_section, ispin, xas_mittle, &
2792 external_matrix_shalf=xas_tdp_env%matrix_shalf)
2796 CALL qs_print_cubes(qs_env, mo_set%mo_coeff, ncubes, state_list, centers, &
2797 print_key=print_key, root=xas_mittle, ispin=ispin, &
2811 IF (do_cubes)
DEALLOCATE (centers, state_list)
2813 CALL timestop(handle)
2815 END SUBROUTINE xas_tdp_post
2825 SUBROUTINE make_lumo_guess(xas_tdp_env, xas_tdp_control, qs_env)
2827 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2828 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2829 TYPE(qs_environment_type),
POINTER :: qs_env
2831 CHARACTER(len=*),
PARAMETER :: routinen =
'make_lumo_guess'
2833 INTEGER :: handle, ispin, nao, nelec_spin(2), &
2834 nlumo(2), nocc(2), nspins
2836 REAL(dp),
ALLOCATABLE,
DIMENSION(:) :: evals
2837 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
2838 TYPE(cp_fm_struct_type),
POINTER :: fm_struct, lumo_struct
2839 TYPE(cp_fm_type) :: amatrix, bmatrix, evecs, work_fm
2840 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_ks, matrix_s
2841 TYPE(mp_para_env_type),
POINTER :: para_env
2843 NULLIFY (matrix_ks, matrix_s, para_env, blacs_env)
2844 NULLIFY (lumo_struct, fm_struct)
2846 CALL timeset(routinen, handle)
2848 do_os = xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks
2849 nspins = 1;
IF (do_os) nspins = 2
2850 ALLOCATE (xas_tdp_env%lumo_evecs(nspins))
2851 ALLOCATE (xas_tdp_env%lumo_evals(nspins))
2852 CALL get_qs_env(qs_env, matrix_ks=matrix_ks, matrix_s=matrix_s, nelectron_spin=nelec_spin, &
2853 para_env=para_env, blacs_env=blacs_env)
2854 CALL dbcsr_get_info(matrix_s(1)%matrix, nfullrows_total=nao)
2857 nlumo = nao - nelec_spin
2860 nlumo = nao - nelec_spin(1)/2
2861 nocc = nelec_spin(1)/2
2864 ALLOCATE (xas_tdp_env%ot_prec(nspins))
2866 DO ispin = 1, nspins
2869 CALL cp_fm_struct_create(fm_struct, para_env=para_env, context=blacs_env, &
2870 nrow_global=nao, ncol_global=nao)
2871 CALL cp_fm_create(amatrix, fm_struct)
2872 CALL cp_fm_create(bmatrix, fm_struct)
2873 CALL cp_fm_create(evecs, fm_struct)
2874 CALL cp_fm_create(work_fm, fm_struct)
2875 ALLOCATE (evals(nao))
2876 ALLOCATE (xas_tdp_env%lumo_evals(ispin)%array(nlumo(ispin)))
2878 CALL copy_dbcsr_to_fm(matrix_ks(ispin)%matrix, amatrix)
2879 CALL copy_dbcsr_to_fm(matrix_s(1)%matrix, bmatrix)
2882 CALL cp_fm_geeig(amatrix, bmatrix, evecs, evals, work_fm)
2885 CALL cp_fm_struct_create(lumo_struct, para_env=para_env, context=blacs_env, &
2886 nrow_global=nao, ncol_global=nlumo(ispin))
2887 CALL cp_fm_create(xas_tdp_env%lumo_evecs(ispin), lumo_struct)
2889 CALL cp_fm_to_fm_submat(evecs, xas_tdp_env%lumo_evecs(ispin), nrow=nao, &
2890 ncol=nlumo(ispin), s_firstrow=1, s_firstcol=nocc(ispin) + 1, &
2891 t_firstrow=1, t_firstcol=1)
2893 xas_tdp_env%lumo_evals(ispin)%array(1:nlumo(ispin)) = evals(nocc(ispin) + 1:nao)
2895 CALL build_ot_spin_prec(evecs, evals, ispin, xas_tdp_env, xas_tdp_control, qs_env)
2898 CALL cp_fm_release(amatrix)
2899 CALL cp_fm_release(bmatrix)
2900 CALL cp_fm_release(evecs)
2901 CALL cp_fm_release(work_fm)
2902 CALL cp_fm_struct_release(fm_struct)
2903 CALL cp_fm_struct_release(lumo_struct)
2907 CALL timestop(handle)
2909 END SUBROUTINE make_lumo_guess
2922 SUBROUTINE build_ot_spin_prec(evecs, evals, ispin, xas_tdp_env, xas_tdp_control, qs_env)
2924 TYPE(cp_fm_type),
INTENT(IN) :: evecs
2925 REAL(dp),
DIMENSION(:) :: evals
2927 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2928 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2929 TYPE(qs_environment_type),
POINTER :: qs_env
2931 CHARACTER(len=*),
PARAMETER :: routinen =
'build_ot_spin_prec'
2933 INTEGER :: handle, nao, nelec_spin(2), nguess, &
2937 REAL(dp),
ALLOCATABLE,
DIMENSION(:) :: scaling
2938 TYPE(cp_fm_struct_type),
POINTER :: fm_struct
2939 TYPE(cp_fm_type) :: fm_prec, work_fm
2940 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_s
2941 TYPE(mp_para_env_type),
POINTER :: para_env
2943 NULLIFY (fm_struct, para_env, matrix_s)
2945 CALL timeset(routinen, handle)
2947 do_os = xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks
2948 CALL get_qs_env(qs_env, para_env=para_env, nelectron_spin=nelec_spin, matrix_s=matrix_s)
2949 CALL cp_fm_get_info(evecs, nrow_global=nao, matrix_struct=fm_struct)
2950 CALL cp_fm_create(fm_prec, fm_struct)
2951 ALLOCATE (scaling(nao))
2952 nocc = nelec_spin(1)/2
2955 nocc = nelec_spin(ispin)
2961 IF (xas_tdp_control%n_excited > 0 .AND. xas_tdp_control%n_excited < nguess)
THEN
2962 nguess = xas_tdp_control%n_excited/nspins
2963 ELSE IF (xas_tdp_control%e_range > 0.0_dp)
THEN
2964 nguess = count(evals(nocc + 1:nao) - evals(nocc + 1) <= xas_tdp_control%e_range)
2968 scaling(nocc + 1:nocc + nguess) = 100.0_dp
2970 shift = evals(nocc + 1) - 0.01_dp
2971 scaling(nocc + nguess:nao) = 1.0_dp/(evals(nocc + nguess:nao) - shift)
2973 scaling(1:nocc) = 1.0_dp
2976 CALL cp_fm_create(work_fm, fm_struct)
2978 CALL cp_fm_copy_general(evecs, work_fm, para_env)
2979 CALL cp_fm_column_scale(work_fm, scaling)
2981 CALL parallel_gemm(
'N',
'T', nao, nao, nao, 1.0_dp, work_fm, evecs, 0.0_dp, fm_prec)
2984 ALLOCATE (xas_tdp_env%ot_prec(ispin)%matrix)
2985 CALL dbcsr_create(xas_tdp_env%ot_prec(ispin)%matrix, template=matrix_s(1)%matrix, name=
"OT_PREC")
2986 CALL copy_fm_to_dbcsr(fm_prec, xas_tdp_env%ot_prec(ispin)%matrix)
2987 CALL dbcsr_filter(xas_tdp_env%ot_prec(ispin)%matrix, xas_tdp_control%eps_filter)
2989 CALL cp_fm_release(work_fm)
2990 CALL cp_fm_release(fm_prec)
2992 CALL timestop(handle)
2994 END SUBROUTINE build_ot_spin_prec
3003 SUBROUTINE print_xps(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
3005 TYPE(donor_state_type),
POINTER :: donor_state
3006 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
3007 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
3008 TYPE(qs_environment_type),
POINTER :: qs_env
3010 INTEGER :: ido_mo, ispin, nspins, output_unit
3011 REAL(dp),
ALLOCATABLE,
DIMENSION(:, :) :: ips, soc_shifts
3013 output_unit = cp_logger_get_default_io_unit()
3015 nspins = 1;
IF (xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks) nspins = 2
3017 ALLOCATE (ips(
SIZE(donor_state%gw2x_evals, 1),
SIZE(donor_state%gw2x_evals, 2)))
3018 ips(:, :) = donor_state%gw2x_evals(:, :)
3021 IF (.NOT. xas_tdp_control%is_periodic)
THEN
3024 IF (donor_state%ndo_mo > 1)
THEN
3025 CALL get_soc_splitting(soc_shifts, donor_state, xas_tdp_env, xas_tdp_control, qs_env)
3026 ips(:, :) = ips(:, :) + soc_shifts
3028 IF (output_unit > 0)
THEN
3029 WRITE (output_unit, fmt=
"(/,T5,A,F23.6)") &
3030 "Ionization potentials for XPS (GW2X + SOC): ", -ips(1, 1)*evolt
3032 DO ispin = 1, nspins
3033 DO ido_mo = 1, donor_state%ndo_mo
3035 IF (ispin == 1 .AND. ido_mo == 1) cycle
3037 WRITE (output_unit, fmt=
"(T5,A,F23.6)") &
3038 " ", -ips(ido_mo, ispin)*evolt
3047 IF (output_unit > 0)
THEN
3048 WRITE (output_unit, fmt=
"(/,T5,A,F29.6)") &
3049 "Ionization potentials for XPS (GW2X): ", -ips(1, 1)*evolt
3051 IF (nspins == 2)
THEN
3052 WRITE (output_unit, fmt=
"(T5,A,F29.6)") &
3053 " ", -ips(1, 2)*evolt
3060 END SUBROUTINE print_xps
3069 SUBROUTINE print_xas_tdp_to_file(donor_state, xas_tdp_env, xas_tdp_control, xas_tdp_section)
3071 TYPE(donor_state_type),
POINTER :: donor_state
3072 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
3073 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
3074 TYPE(section_vals_type),
POINTER :: xas_tdp_section
3076 INTEGER :: i, output_unit, xas_tdp_unit
3077 TYPE(cp_logger_type),
POINTER :: logger
3080 logger => cp_get_default_logger()
3082 xas_tdp_unit = cp_print_key_unit_nr(logger, xas_tdp_section,
"PRINT%SPECTRUM", &
3083 extension=
".spectrum", file_position=
"APPEND", &
3084 file_action=
"WRITE", file_form=
"FORMATTED")
3086 output_unit = cp_logger_get_default_io_unit()
3088 IF (output_unit > 0)
THEN
3089 WRITE (output_unit, fmt=
"(/,T5,A,/)") &
3090 "Calculations done: "
3093 IF (xas_tdp_control%do_spin_cons)
THEN
3094 IF (xas_tdp_unit > 0)
THEN
3097 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3098 "==================================================================================", &
3099 "XAS TDP open-shell spin-conserving (no SOC) excitations for DONOR STATE: ", &
3100 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3101 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3102 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3103 "=================================================================================="
3107 IF (xas_tdp_control%do_quad)
THEN
3108 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3109 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3110 DO i = 1,
SIZE(donor_state%sc_evals)
3111 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3112 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4), &
3113 donor_state%quad_osc_str(i)
3115 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3116 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3117 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3118 DO i = 1,
SIZE(donor_state%sc_evals)
3119 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3120 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4), &
3121 donor_state%osc_str(i, 1), donor_state%osc_str(i, 2), donor_state%osc_str(i, 3)
3123 ELSE IF (xas_tdp_control%spin_dip)
THEN
3124 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3125 " Index Excitation energy (eV) fosc dipole (a.u.) alpha-comp beta-comp"
3126 DO i = 1,
SIZE(donor_state%sc_evals)
3127 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6)") &
3128 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4), &
3129 donor_state%alpha_osc(i, 4), donor_state%beta_osc(i, 4)
3132 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3133 " Index Excitation energy (eV) fosc dipole (a.u.)"
3134 DO i = 1,
SIZE(donor_state%sc_evals)
3135 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3136 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4)
3140 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3143 IF (output_unit > 0)
THEN
3144 WRITE (output_unit, fmt=
"(T5,A,F17.6)") &
3145 "First spin-conserving XAS excitation energy (eV): ", donor_state%sc_evals(1)*evolt
3150 IF (xas_tdp_control%do_spin_flip)
THEN
3151 IF (xas_tdp_unit > 0)
THEN
3154 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3155 "==================================================================================", &
3156 "XAS TDP open-shell spin-flip (no SOC) excitations for DONOR STATE: ", &
3157 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3158 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3159 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3160 "=================================================================================="
3164 IF (xas_tdp_control%do_quad)
THEN
3165 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3166 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3167 DO i = 1,
SIZE(donor_state%sf_evals)
3168 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3169 i, donor_state%sf_evals(i)*evolt, 0.0_dp, 0.0_dp
3171 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3172 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3173 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3174 DO i = 1,
SIZE(donor_state%sf_evals)
3175 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3176 i, donor_state%sf_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp
3178 ELSE IF (xas_tdp_control%spin_dip)
THEN
3179 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3180 " Index Excitation energy (eV) fosc dipole (a.u.) alpha-comp beta-comp"
3181 DO i = 1,
SIZE(donor_state%sf_evals)
3182 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6)") &
3183 i, donor_state%sf_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp
3186 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3187 " Index Excitation energy (eV) fosc dipole (a.u.)"
3188 DO i = 1,
SIZE(donor_state%sf_evals)
3189 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3190 i, donor_state%sf_evals(i)*evolt, 0.0_dp
3194 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3197 IF (output_unit > 0)
THEN
3198 WRITE (output_unit, fmt=
"(T5,A,F23.6)") &
3199 "First spin-flip XAS excitation energy (eV): ", donor_state%sf_evals(1)*evolt
3203 IF (xas_tdp_control%do_singlet)
THEN
3204 IF (xas_tdp_unit > 0)
THEN
3207 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3208 "==================================================================================", &
3209 "XAS TDP singlet excitations (no SOC) for DONOR STATE: ", &
3210 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3211 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3212 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3213 "=================================================================================="
3217 IF (xas_tdp_control%do_quad)
THEN
3218 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3219 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3220 DO i = 1,
SIZE(donor_state%sg_evals)
3221 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3222 i, donor_state%sg_evals(i)*evolt, donor_state%osc_str(i, 4), &
3223 donor_state%quad_osc_str(i)
3225 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3226 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3227 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3228 DO i = 1,
SIZE(donor_state%sg_evals)
3229 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3230 i, donor_state%sg_evals(i)*evolt, donor_state%osc_str(i, 4), &
3231 donor_state%osc_str(i, 1), donor_state%osc_str(i, 2), donor_state%osc_str(i, 3)
3234 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3235 " Index Excitation energy (eV) fosc dipole (a.u.)"
3236 DO i = 1,
SIZE(donor_state%sg_evals)
3237 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3238 i, donor_state%sg_evals(i)*evolt, donor_state%osc_str(i, 4)
3242 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3245 IF (output_unit > 0)
THEN
3246 WRITE (output_unit, fmt=
"(T5,A,F25.6)") &
3247 "First singlet XAS excitation energy (eV): ", donor_state%sg_evals(1)*evolt
3251 IF (xas_tdp_control%do_triplet)
THEN
3252 IF (xas_tdp_unit > 0)
THEN
3255 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3256 "==================================================================================", &
3257 "XAS TDP triplet excitations (no SOC) for DONOR STATE: ", &
3258 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3259 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3260 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3261 "=================================================================================="
3265 IF (xas_tdp_control%do_quad)
THEN
3266 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3267 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3268 DO i = 1,
SIZE(donor_state%tp_evals)
3269 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3270 i, donor_state%tp_evals(i)*evolt, 0.0_dp, 0.0_dp
3272 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3273 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3274 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3275 DO i = 1,
SIZE(donor_state%tp_evals)
3276 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3277 i, donor_state%tp_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp
3279 ELSE IF (xas_tdp_control%spin_dip)
THEN
3280 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3281 " Index Excitation energy (eV) fosc dipole (a.u.) alpha-comp beta-comp"
3282 DO i = 1,
SIZE(donor_state%tp_evals)
3283 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6)") &
3284 i, donor_state%tp_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp
3287 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3288 " Index Excitation energy (eV) fosc dipole (a.u.)"
3289 DO i = 1,
SIZE(donor_state%tp_evals)
3290 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3291 i, donor_state%tp_evals(i)*evolt, 0.0_dp
3295 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3298 IF (output_unit > 0)
THEN
3299 WRITE (output_unit, fmt=
"(T5,A,F25.6)") &
3300 "First triplet XAS excitation energy (eV): ", donor_state%tp_evals(1)*evolt
3304 IF (xas_tdp_control%do_soc .AND. donor_state%state_type == xas_2p_type)
THEN
3305 IF (xas_tdp_unit > 0)
THEN
3308 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3309 "==================================================================================", &
3310 "XAS TDP excitations after spin-orbit coupling for DONOR STATE: ", &
3311 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3312 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3313 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3314 "=================================================================================="
3317 IF (xas_tdp_control%do_quad)
THEN
3318 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3319 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3320 DO i = 1,
SIZE(donor_state%soc_evals)
3321 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3322 i, donor_state%soc_evals(i)*evolt, donor_state%soc_osc_str(i, 4), &
3323 donor_state%soc_quad_osc_str(i)
3325 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3326 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3327 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3328 DO i = 1,
SIZE(donor_state%soc_evals)
3329 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3330 i, donor_state%soc_evals(i)*evolt, donor_state%soc_osc_str(i, 4), &
3331 donor_state%soc_osc_str(i, 1), donor_state%soc_osc_str(i, 2), donor_state%soc_osc_str(i, 3)
3334 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3335 " Index Excitation energy (eV) fosc dipole (a.u.)"
3336 DO i = 1,
SIZE(donor_state%soc_evals)
3337 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3338 i, donor_state%soc_evals(i)*evolt, donor_state%soc_osc_str(i, 4)
3342 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3345 IF (output_unit > 0)
THEN
3346 WRITE (output_unit, fmt=
"(T5,A,F29.6)") &
3347 "First SOC XAS excitation energy (eV): ", donor_state%soc_evals(1)*evolt
3351 CALL cp_print_key_finished_output(xas_tdp_unit, logger, xas_tdp_section,
"PRINT%SPECTRUM")
3353 END SUBROUTINE print_xas_tdp_to_file
3363 SUBROUTINE write_donor_state_restart(ex_type, donor_state, xas_tdp_section, qs_env)
3365 INTEGER,
INTENT(IN) :: ex_type
3366 TYPE(donor_state_type),
POINTER :: donor_state
3367 TYPE(section_vals_type),
POINTER :: xas_tdp_section
3368 TYPE(qs_environment_type),
POINTER :: qs_env
3370 CHARACTER(len=*),
PARAMETER :: routinen =
'write_donor_state_restart'
3372 CHARACTER(len=default_path_length) :: filename
3373 CHARACTER(len=default_string_length) :: domo, excite, my_middle
3374 INTEGER :: ex_atom, handle, ispin, nao, ndo_mo, &
3375 nex, nspins, output_unit, rst_unit, &
3377 INTEGER,
DIMENSION(:, :),
POINTER :: mo_indices
3379 REAL(dp),
DIMENSION(:),
POINTER :: lr_evals
3380 TYPE(cp_fm_type),
POINTER :: lr_coeffs
3381 TYPE(cp_logger_type),
POINTER :: logger
3382 TYPE(mo_set_type),
DIMENSION(:),
POINTER :: mos
3383 TYPE(section_vals_type),
POINTER :: print_key
3385 NULLIFY (logger, lr_coeffs, lr_evals, print_key, mos)
3388 logger => cp_get_default_logger()
3390 IF (btest(cp_print_key_should_output(logger%iter_info, xas_tdp_section, &
3391 "PRINT%RESTART", used_print_key=print_key), cp_p_file)) do_print = .true.
3393 IF (.NOT. do_print)
RETURN
3395 CALL timeset(routinen, handle)
3397 output_unit = cp_logger_get_default_io_unit()
3400 SELECT CASE (ex_type)
3401 CASE (tddfpt_spin_cons)
3402 lr_evals => donor_state%sc_evals
3403 lr_coeffs => donor_state%sc_coeffs
3406 CASE (tddfpt_spin_flip)
3407 lr_evals => donor_state%sf_evals
3408 lr_coeffs => donor_state%sf_coeffs
3411 CASE (tddfpt_singlet)
3412 lr_evals => donor_state%sg_evals
3413 lr_coeffs => donor_state%sg_coeffs
3416 CASE (tddfpt_triplet)
3417 lr_evals => donor_state%tp_evals
3418 lr_coeffs => donor_state%tp_coeffs
3423 SELECT CASE (donor_state%state_type)
3432 ndo_mo = donor_state%ndo_mo
3433 nex =
SIZE(lr_evals)
3434 CALL cp_fm_get_info(lr_coeffs, nrow_global=nao)
3435 state_type = donor_state%state_type
3436 ex_atom = donor_state%at_index
3437 mo_indices => donor_state%mo_indices
3441 my_middle =
'xasat'//trim(adjustl(cp_to_string(ex_atom)))//
'_'//trim(domo)//
'_'//trim(excite)
3442 rst_unit = cp_print_key_unit_nr(logger, xas_tdp_section,
"PRINT%RESTART", extension=
".rst", &
3443 file_status=
"REPLACE", file_action=
"WRITE", &
3444 file_form=
"UNFORMATTED", middle_name=trim(my_middle))
3446 filename = cp_print_key_generate_filename(logger, print_key, middle_name=trim(my_middle), &
3447 extension=
".rst", my_local=.false.)
3449 IF (output_unit > 0)
THEN
3450 WRITE (unit=output_unit, fmt=
"(/,T5,A,/T5,A,A,A)") &
3451 "Linear-response orbitals and excitation energies are written in: ", &
3452 '"', trim(filename),
'"'
3456 IF (rst_unit > 0)
THEN
3457 WRITE (rst_unit) ex_atom, state_type, ndo_mo, ex_type
3458 WRITE (rst_unit) nao, nex, nspins
3459 WRITE (rst_unit) mo_indices(:, :)
3460 WRITE (rst_unit) lr_evals(:)
3462 CALL cp_fm_write_unformatted(lr_coeffs, rst_unit)
3465 CALL get_qs_env(qs_env, mos=mos)
3466 DO ispin = 1, nspins
3467 CALL cp_fm_write_unformatted(mos(ispin)%mo_coeff, rst_unit)
3471 CALL cp_print_key_finished_output(rst_unit, logger, xas_tdp_section,
"PRINT%RESTART")
3473 CALL timestop(handle)
3475 END SUBROUTINE write_donor_state_restart
3484 SUBROUTINE read_donor_state_restart(donor_state, ex_type, filename, qs_env)
3486 TYPE(donor_state_type),
POINTER :: donor_state
3487 INTEGER,
INTENT(OUT) :: ex_type
3488 CHARACTER(len=*),
INTENT(IN) :: filename
3489 TYPE(qs_environment_type),
POINTER :: qs_env
3491 CHARACTER(len=*),
PARAMETER :: routinen =
'read_donor_state_restart'
3493 INTEGER :: handle, ispin, nao, nex, nspins, &
3494 output_unit, read_params(7), rst_unit
3495 INTEGER,
DIMENSION(:, :),
POINTER :: mo_indices
3496 LOGICAL :: file_exists
3497 REAL(dp),
DIMENSION(:),
POINTER :: lr_evals
3498 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
3499 TYPE(cp_fm_struct_type),
POINTER :: fm_struct
3500 TYPE(cp_fm_type),
POINTER :: lr_coeffs
3501 TYPE(mo_set_type),
DIMENSION(:),
POINTER :: mos
3502 TYPE(mp_comm_type) :: group
3503 TYPE(mp_para_env_type),
POINTER :: para_env
3505 NULLIFY (lr_evals, lr_coeffs, para_env, fm_struct, blacs_env, mos)
3507 CALL timeset(routinen, handle)
3509 output_unit = cp_logger_get_default_io_unit()
3510 cpassert(
ASSOCIATED(donor_state))
3511 CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
3514 file_exists = .false.
3517 IF (para_env%is_source())
THEN
3519 INQUIRE (file=filename, exist=file_exists)
3520 IF (.NOT. file_exists) cpabort(
"Trying to read non-existing XAS_TDP restart file")
3522 CALL open_file(file_name=trim(filename), file_action=
"READ", file_form=
"UNFORMATTED", &
3523 file_position=
"REWIND", file_status=
"OLD", unit_number=rst_unit)
3526 IF (output_unit > 0)
THEN
3527 WRITE (unit=output_unit, fmt=
"(/,T5,A,/,T5,A,A,A)") &
3528 "Reading linear-response orbitals and excitation energies from file: ", &
3533 IF (rst_unit > 0)
THEN
3534 READ (rst_unit) read_params(1:4)
3535 READ (rst_unit) read_params(5:7)
3537 CALL group%bcast(read_params)
3538 donor_state%at_index = read_params(1)
3539 donor_state%state_type = read_params(2)
3540 donor_state%ndo_mo = read_params(3)
3541 ex_type = read_params(4)
3542 nao = read_params(5)
3543 nex = read_params(6)
3544 nspins = read_params(7)
3546 ALLOCATE (mo_indices(donor_state%ndo_mo, nspins))
3547 IF (rst_unit > 0)
THEN
3548 READ (rst_unit) mo_indices(1:donor_state%ndo_mo, 1:nspins)
3550 CALL group%bcast(mo_indices)
3551 donor_state%mo_indices => mo_indices
3554 ALLOCATE (lr_evals(nex))
3555 IF (rst_unit > 0)
READ (rst_unit) lr_evals(1:nex)
3556 CALL group%bcast(lr_evals)
3559 CALL cp_fm_struct_create(fm_struct, context=blacs_env, para_env=para_env, &
3560 nrow_global=nao, ncol_global=nex*donor_state%ndo_mo*nspins)
3561 ALLOCATE (lr_coeffs)
3562 CALL cp_fm_create(lr_coeffs, fm_struct)
3563 CALL cp_fm_read_unformatted(lr_coeffs, rst_unit)
3564 CALL cp_fm_struct_release(fm_struct)
3567 CALL get_qs_env(qs_env, mos=mos)
3568 DO ispin = 1, nspins
3569 CALL cp_fm_read_unformatted(mos(ispin)%mo_coeff, rst_unit)
3573 IF (para_env%is_source())
THEN
3574 CALL close_file(unit_number=rst_unit)
3578 SELECT CASE (ex_type)
3579 CASE (tddfpt_spin_cons)
3580 donor_state%sc_evals => lr_evals
3581 donor_state%sc_coeffs => lr_coeffs
3582 CASE (tddfpt_spin_flip)
3583 donor_state%sf_evals => lr_evals
3584 donor_state%sf_coeffs => lr_coeffs
3585 CASE (tddfpt_singlet)
3586 donor_state%sg_evals => lr_evals
3587 donor_state%sg_coeffs => lr_coeffs
3588 CASE (tddfpt_triplet)
3589 donor_state%tp_evals => lr_evals
3590 donor_state%tp_coeffs => lr_coeffs
3593 CALL timestop(handle)
3595 END SUBROUTINE read_donor_state_restart
3603 SUBROUTINE restart_calculation(rst_filename, xas_tdp_section, qs_env)
3605 CHARACTER(len=*),
INTENT(IN) :: rst_filename
3606 TYPE(section_vals_type),
POINTER :: xas_tdp_section
3607 TYPE(qs_environment_type),
POINTER :: qs_env
3610 TYPE(donor_state_type),
POINTER :: donor_state
3611 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
3613 NULLIFY (xas_tdp_env, donor_state)
3616 ALLOCATE (donor_state)
3617 CALL donor_state_create(donor_state)
3618 CALL read_donor_state_restart(donor_state, ex_type, rst_filename, qs_env)
3621 CALL xas_tdp_env_create(xas_tdp_env)
3622 CALL xas_tdp_post(ex_type, donor_state, xas_tdp_env, xas_tdp_section, qs_env)
3625 CALL xas_tdp_env_release(xas_tdp_env)
3626 CALL free_ds_memory(donor_state)
3627 DEALLOCATE (donor_state%mo_indices)
3628 DEALLOCATE (donor_state)
3630 END SUBROUTINE restart_calculation
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
Types and set/get functions for auxiliary density matrix methods.
Contains methods used in the context of density fitting.
subroutine, public admm_uncorrect_for_eigenvalues(ispin, admm_env, ks_matrix)
...
subroutine, public admm_correct_for_eigenvalues(ispin, admm_env, ks_matrix)
...
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
subroutine, public get_gto_basis_set(gto_basis_set, name, aliases, norm_type, kind_radius, ncgf, nset, nsgf, cgf_symbol, sgf_symbol, norm_cgf, set_radius, lmax, lmin, lx, ly, lz, m, ncgf_set, npgf, nsgf_set, nshell, cphi, pgf_radius, sphi, scon, zet, first_cgf, first_sgf, l, last_cgf, last_sgf, n, gcc, maxco, maxl, maxpgf, maxsgf_set, maxshell, maxso, nco_sum, npgf_sum, nshell_sum, maxder, short_kind_radius, npgf_seg_sum, ccon)
...
subroutine, public create_gto_from_sto_basis(sto_basis_set, gto_basis_set, ngauss, ortho, ngaussflex)
...
subroutine, public deallocate_gto_basis_set(gto_basis_set)
...
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 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.
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public bussy2021a
Handles all functions related to the CELL.
methods related to the blacs parallel environment
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_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)
...
subroutine, public dbcsr_filter(matrix, eps)
...
real(kind=dp) function, public dbcsr_get_occupation(matrix)
...
subroutine, public dbcsr_finalize(matrix)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_complete_redistribute(matrix, redist)
...
subroutine, public dbcsr_add_on_diag(matrix, alpha)
Adds the given scalar to the diagonal of the matrix. Reserves any missing diagonal blocks.
subroutine, public dbcsr_reserve_all_blocks(matrix)
Reserves all blocks.
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, plan, check_plan)
Copy a DBCSR matrix to a BLACS matrix.
subroutine, public copy_fm_to_dbcsr(fm, matrix, keep_sparsity)
Copy a BLACS matrix to a dbcsr matrix.
Utility routines to open and close files.
subroutine, public open_file(file_name, unit_number, file_status, file_form, file_action, file_position, file_pad, file_access, debug)
Opens a file and returns its logical unit number.
subroutine, public close_file(unit_number, file_status)
Closes an open file given by its logical unit number.
Basic linear algebra operations for full matrices.
subroutine, public cp_fm_column_scale(matrixa, scaling, first_col, source)
Scales columns of the full matrix by corresponding factors.
used for collecting some of the diagonalization schemes available for cp_fm_type. cp_fm_power also mo...
subroutine, public cp_fm_power(matrix, work, exponent, threshold, n_dependent, verbose, eigvals)
...
subroutine, public cp_fm_syevd(matrix, eigenvectors, eigenvalues, info)
Computes all eigenvalues and vectors of a real symmetric matrix significantly faster than syevx,...
subroutine, public cp_fm_geeig(amatrix, bmatrix, eigenvectors, eigenvalues, work)
General Eigenvalue Problem AX = BXE. Use cuSOLVERMp directly when requested and large enough; otherwi...
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
subroutine, public cp_fm_copy_general(source, destination, para_env)
General copy of a fm matrix to another fm matrix. Uses non-blocking MPI rather than ScaLAPACK.
subroutine, public cp_fm_write_unformatted(fm, unit, ncol)
...
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_get_diag(matrix, diag, n_active)
returns the diagonal elements of a fm
subroutine, public cp_fm_read_unformatted(fm, unit)
...
subroutine, public cp_fm_to_fm_submat(msource, mtarget, nrow, ncol, s_firstrow, s_firstcol, t_firstrow, t_firstcol)
copy just a part ot the matrix
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_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
creates a new full matrix with the given structure
subroutine, public cp_fm_get_submatrix(fm, target_m, start_row, start_col, n_rows, n_cols, transpose)
gets a submatrix of a full matrix op(target_m)(1:n_rows,1:n_cols) =fm(start_row:start_row+n_rows,...
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
character(len=default_path_length) function, public cp_print_key_generate_filename(logger, print_key, middle_name, extension, my_local)
Utility function that returns a unit number to write the print key. Might open a file with a unique f...
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 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 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, file_access)
...
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
integer, parameter, public default_path_length
An array-based list which grows on demand. When the internal array is full, a new array of twice the ...
Machine interface based on Fortran 2003 and POSIX.
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Collection of simple mathematical functions and subroutines.
pure real(kind=dp) function, dimension(min(size(a, 1), size(a, 2))), public get_diag(a)
Return the diagonal elements of matrix a as a vector.
subroutine, public diag(n, a, d, v)
Diagonalize matrix a. The eigenvalues are returned in vector d and the eigenvectors are returned in m...
Utility routines for the memory handling.
Interface to the message passing library MPI.
basic linear algebra operations for full matrixes
Parallel (pseudo)random number generator (RNG) for multiple streams and substreams of random numbers.
integer, parameter, public uniform
Define methods related to particle_type.
subroutine, public get_particle_set(particle_set, qs_kind_set, first_sgf, last_sgf, nsgf, nmao, basis, ncgf)
Get the components of a particle set.
Define the data structure for the particle information.
Periodic Table related data definitions.
type(atom), dimension(0:nelem), public ptable
Definition of physical constants:
real(kind=dp), parameter, public a_fine
real(kind=dp), parameter, public evolt
real(kind=dp), parameter, public angstrom
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, matrix_vhxc, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Calculate the interaction radii for the operator matrix calculation.
subroutine, public init_interaction_radii_orb_basis(orb_basis_set, eps_pgf_orb, eps_pgf_short)
...
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, cneo_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, hund_j, u_of_dft_plus_u, j_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, j0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, proj_shell_charge, lr_atom, do_mtlr, u_j_loop, ao_coef, init_u_ramping_each_scf, reltmat, ghost, monovalent, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
Driver for the localization that should be general for all the methods available and all the definiti...
subroutine, public qs_loc_driver(qs_env, qs_loc_env, print_loc_section, myspin, ext_mo_coeff)
set up the calculation of localized orbitals
Driver for the localization that should be general for all the methods available and all the definiti...
subroutine, public qs_print_cubes(qs_env, mo_coeff, nstates, state_list, centers, print_key, root, ispin, idir, state0, file_position)
write the cube files for a set of selected states
subroutine, public centers_spreads_berry(qs_loc_env, nmoloc, cell, weights, ispin, print_loc_section, zij, c_zij, only_initial_out)
...
New version of the module for the localization of the molecular orbitals This should be able to use d...
subroutine, public localized_wfn_control_create(localized_wfn_control)
create the localized_wfn_control_type
subroutine, public qs_loc_env_release(qs_loc_env)
...
subroutine, public get_qs_loc_env(qs_loc_env, cell, local_molecules, localized_wfn_control, moloc_coeff, op_sm_set, op_fm_set, para_env, particle_set, weights, dim_op)
...
subroutine, public qs_loc_env_create(qs_loc_env)
...
Some utilities for the construction of the localization environment.
subroutine, public qs_loc_env_init(qs_loc_env, localized_wfn_control, qs_env, myspin, do_localize, loc_coeff, mo_loc_history)
allocates the data, and initializes the operators
subroutine, public set_loc_centers(localized_wfn_control, nmoloc, nspins)
create the center and spread array and the file names for the output
subroutine, public qs_loc_control_init(qs_loc_env, loc_section, do_homo, do_mixed, do_xas, nloc_xas, spin_xas)
initializes everything needed for localization of the HOMOs
Definition and initialisation of the mo data type.
subroutine, public write_mo_set_low(mo_array, qs_kind_set, particle_set, ires, rt_mos, matrix_ks)
...
collects routines that perform operations directly related to MOs
Definition and initialisation of the mo data type.
subroutine, public duplicate_mo_set(mo_set_new, mo_set_old)
allocate a new mo_set, and copy the old data
subroutine, public init_mo_set(mo_set, fm_pool, fm_ref, fm_struct, name, counter, complex_coeff)
initializes an allocated mo_set. eigenvalues, mo_coeff, occupation_numbers are valid only after this ...
subroutine, public allocate_mo_set(mo_set, nao, nmo, nelectron, n_el_f, maxocc, flexible_electron_count)
Allocates a mo set and partially initializes it (nao,nmo,nelectron, and flexible_electron_count are v...
subroutine, public deallocate_mo_set(mo_set)
Deallocate a wavefunction data structure.
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, cmo_coeff)
Get the components of a MO set data structure.
Calculates the moment integrals <a|r^m|b> and <a|r x d/dr|b>.
subroutine, public build_local_moment_matrix(qs_env, moments, nmoments, ref_point, ref_points, basis_type, all_images, minimum_image, neighbor_image, first_component)
...
subroutine, public build_lin_mom_matrix(qs_env, matrix, minimum_image)
Calculation of the linear momentum matrix <mu|∂|nu> over Cartesian Gaussian functions.
Calculation and writing of projected density of states The DOS is computed per angular momentum and p...
subroutine, public calculate_projected_dos(mo_set, atomic_kind_set, qs_kind_set, particle_set, qs_env, dft_section, ispin, xas_mittle, external_matrix_shalf, unoccupied_orbs, unoccupied_evals, pdos_print_key, write_pdos, write_pdos_curve)
Compute and write projected density of states.
module that contains the definitions of the scf types
integer, parameter, public ot_method_nr
Define Resonant Inelastic XRAY Scattering (RIXS) control type and associated create,...
All kind of helpful little routines.
pure integer function, public locate(array, x)
Purpose: Given an array array(1:n), and given a value x, a value x_index is returned which is the ind...
pure integer function, dimension(2), public get_limit(m, n, me)
divide m entries into n parts, return size of part me
driver for the xas calculation and xas_scf for the tp method
subroutine, public calc_stogto_overlap(base_a, base_b, matrix)
...
This module deals with all the integrals done on local atomic grids in xas_tdp. This is mostly used t...
subroutine, public init_xas_atom_env(xas_atom_env, xas_tdp_env, xas_tdp_control, qs_env, ltddfpt)
Initializes a xas_atom_env type given the qs_enxas_atom_env, qs_envv.
subroutine, public integrate_soc_atoms(matrix_soc, xas_atom_env, qs_env, soc_atom_env)
Computes the SOC matrix elements with respect to the ORB basis set for each atomic kind and put them ...
subroutine, public integrate_fxc_atoms(int_fxc, xas_atom_env, xas_tdp_control, qs_env)
Integrate the xc kernel as a function of r on the atomic grids for the RI_XAS basis.
Second order perturbation correction to XAS_TDP spectra (i.e. shift).
subroutine, public gw2x_shift(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
Computes the ionization potential using the GW2X method of Shigeta et. al. The result cam be used for...
subroutine, public get_soc_splitting(soc_shifts, donor_state, xas_tdp_env, xas_tdp_control, qs_env)
We try to compute the spin-orbit splitting via perturbation theory. We keep it \ cheap by only inculd...
3-center integrals machinery for the XAS_TDP method
subroutine, public compute_ri_coulomb2_int(ex_kind, xas_tdp_env, xas_tdp_control, qs_env)
Computes the two-center Coulomb integral needed for the RI in kernel calculation. Stores the integral...
subroutine, public compute_ri_3c_coulomb(xas_tdp_env, qs_env)
Computes the RI Coulomb 3-center integrals (ab|c), where c is from the RI_XAS basis and centered on t...
subroutine, public compute_ri_exchange2_int(ex_kind, xas_tdp_env, xas_tdp_control, qs_env)
Computes the two-center Exchange integral needed for the RI in kernel calculation....
subroutine, public compute_ri_3c_exchange(ex_atoms, xas_tdp_env, xas_tdp_control, qs_env)
Computes the RI exchange 3-center integrals (ab|c), where c is from the RI_XAS basis and centered on ...
Methods for X-Ray absorption spectroscopy (XAS) using TDDFPT.
subroutine, public xas_tdp_init(xas_tdp_env, xas_tdp_control, qs_env, rixs_env)
Overall control and environment types initialization.
subroutine, public xas_tdp(qs_env, rixs_env)
Driver for XAS TDDFT calculations.
Define XAS TDP control type and associated create, release, etc subroutines, as well as XAS TDP envir...
subroutine, public xas_tdp_env_create(xas_tdp_env)
Creates a TDP XAS environment type.
subroutine, public xas_tdp_env_release(xas_tdp_env)
Releases the TDP XAS environment type.
subroutine, public donor_state_create(donor_state)
Creates a donor_state.
subroutine, public xas_tdp_control_release(xas_tdp_control)
Releases the xas_tdp_control_type.
subroutine, public xas_atom_env_create(xas_atom_env)
Creates a xas_atom_env type.
subroutine, public set_xas_tdp_env(xas_tdp_env, nex_atoms, nex_kinds)
Sets values of selected variables within the TDP XAS environment type.
subroutine, public free_ds_memory(donor_state)
Deallocate a donor_state's heavy attributes.
subroutine, public set_donor_state(donor_state, at_index, at_symbol, kind_index, state_type)
sets specified values of the donor state type
subroutine, public xas_tdp_control_create(xas_tdp_control)
Creates and initializes the xas_tdp_control_type.
subroutine, public free_exat_memory(xas_tdp_env, atom, end_of_batch)
Releases the memory heavy attribute of xas_tdp_env that are specific to the current excited atom.
subroutine, public xas_atom_env_release(xas_atom_env)
Releases the xas_atom_env type.
subroutine, public read_xas_tdp_control(xas_tdp_control, xas_tdp_section)
Reads the inputs and stores in xas_tdp_control_type.
Utilities for X-ray absorption spectroscopy using TDDFPT.
subroutine, public include_rcs_soc(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
Includes the SOC effects on the precomputed restricted closed-shell singlet and triplet excitations....
subroutine, public setup_xas_tdp_prob(donor_state, qs_env, xas_tdp_env, xas_tdp_control)
Builds the matrix that defines the XAS TDDFPT generalized eigenvalue problem to be solved for excitat...
subroutine, public solve_xas_tdp_prob(donor_state, xas_tdp_control, xas_tdp_env, qs_env, ex_type)
Solves the XAS TDP generalized eigenvalue problem omega*C = matrix_tdp*C using standard full diagonal...
subroutine, public include_os_soc(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
Includes the SOC effects on the precomputed spin-conserving and spin-flip excitations from an open-sh...
Writes information on XC functionals to output.
subroutine, public xc_write(iounit, xc_section, lsd)
...
stores some data used in wavefunction fitting
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
keeps the information about the structure of 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
Provides all information about a quickstep kind.
A type that holds controlling information for the calculation of the spread of wfn and the optimizati...
contains all the info needed by quickstep to calculate the spread of a selected set of orbitals and i...
Type containing informations about a single donor state.
a environment type that contains all the info needed for XAS_TDP atomic grid calculations
Type containing control information for TDP XAS calculations.
Type containing informations such as inputs and results for TDP XAS calculations.