148#include "./base/base_uses.f90"
153 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'xas_tdp_methods'
171 CHARACTER(len=*),
PARAMETER :: routinen =
'xas_tdp'
173 CHARACTER(default_string_length) :: rst_filename
174 INTEGER :: handle, n_rep, output_unit
175 LOGICAL :: do_restart, do_rixs
178 CALL timeset(routinen, handle)
181 NULLIFY (xas_tdp_section)
192 IF (output_unit > 0)
THEN
193 WRITE (unit=output_unit, fmt=
"(/,T3,A,/,T3,A,/,T3,A,/,T3,A,/)") &
194 "!===========================================================================!", &
196 "! Starting TDDFPT driven X-rays absorption spectroscopy calculations !", &
197 "!===========================================================================!"
215 IF (output_unit > 0)
THEN
216 WRITE (unit=output_unit, fmt=
"(/,T3,A)") &
217 "# This is a RESTART calculation for PDOS and/or CUBE printing"
220 CALL restart_calculation(rst_filename, xas_tdp_section, qs_env)
224 IF (
PRESENT(rixs_env))
THEN
225 CALL xas_tdp_core(xas_tdp_section, qs_env, rixs_env)
227 CALL xas_tdp_core(xas_tdp_section, qs_env)
231 IF (output_unit > 0)
THEN
232 WRITE (unit=output_unit, fmt=
"(/,T3,A,/,T3,A,/,T3,A,/)") &
233 "!===========================================================================!", &
234 "! End of TDDFPT driven X-rays absorption spectroscopy calculations !", &
235 "!===========================================================================!"
238 CALL timestop(handle)
248 SUBROUTINE xas_tdp_core(xas_tdp_section, qs_env, rixs_env)
254 CHARACTER(LEN=default_string_length) :: kind_name
255 INTEGER :: batch_size, bo(2), current_state_index, iat, iatom, ibatch, ikind, ispin, istate, &
256 nbatch, nex_atom, output_unit, tmp_index
257 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: batch_atoms, ex_atoms_of_kind
258 INTEGER,
DIMENSION(:),
POINTER :: atoms_of_kind
259 LOGICAL :: do_os, do_rixs, end_of_batch, unique
266 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
271 NULLIFY (xas_tdp_env, xas_tdp_control, atomic_kind_set, atoms_of_kind, current_state)
272 NULLIFY (xas_atom_env, dft_control, matrix_ks, admm_env, qs_kind_set, tmp_basis)
277 IF (output_unit > 0)
THEN
278 WRITE (unit=output_unit, fmt=
"(/,T3,A)") &
279 "# Create and initialize the XAS_TDP environment"
281 CALL get_qs_env(qs_env, dft_control=dft_control, do_rixs=do_rixs)
282 IF (
PRESENT(rixs_env))
THEN
283 CALL xas_tdp_init(xas_tdp_env, xas_tdp_control, qs_env, rixs_env)
287 CALL print_info(output_unit, xas_tdp_control, qs_env)
289 IF (output_unit > 0)
THEN
290 IF (xas_tdp_control%check_only)
THEN
291 cpwarn(
"This is a CHECK_ONLY run for donor MOs verification")
296 IF (xas_tdp_control%do_loc)
THEN
297 IF (output_unit > 0)
THEN
298 WRITE (unit=output_unit, fmt=
"(/,T3,A,/)") &
299 "# Localizing core orbitals for better identification"
302 IF (xas_tdp_control%do_uks)
THEN
303 DO ispin = 1, dft_control%nspins
305 xas_tdp_control%print_loc_subsection, myspin=ispin)
309 xas_tdp_control%print_loc_subsection, myspin=1)
314 CALL find_mo_centers(xas_tdp_env, xas_tdp_control, qs_env)
317 CALL assign_mos_to_ex_atoms(xas_tdp_env, xas_tdp_control, qs_env)
320 IF (xas_tdp_control%do_loc)
THEN
321 IF (output_unit > 0)
THEN
322 WRITE (unit=output_unit, fmt=
"(/,T3,A,/,T5,A)") &
323 "# Diagonalize localized MOs wrt the KS matrix in the subspace of each excited", &
324 "atom for better donor state identification."
326 CALL diagonalize_assigned_mo_subset(xas_tdp_env, xas_tdp_control, qs_env)
328 CALL find_mo_centers(xas_tdp_env, xas_tdp_control, qs_env)
331 IF (output_unit > 0)
THEN
332 WRITE (unit=output_unit, fmt=
"(/,T3,A,I4,A,/)") &
333 "# Assign the relevant subset of the ", xas_tdp_control%n_search, &
334 " lowest energy MOs to excited atoms"
336 CALL write_mos_to_ex_atoms_association(xas_tdp_env, xas_tdp_control, qs_env)
339 IF (xas_tdp_control%check_only)
CALL print_checks(xas_tdp_env, xas_tdp_control, qs_env)
343 IF ((xas_tdp_control%do_xc .OR. xas_tdp_control%do_soc .OR. xas_tdp_control%do_gw2x) &
344 .AND. .NOT. xas_tdp_control%check_only)
THEN
346 IF (output_unit > 0 .AND. xas_tdp_control%do_xc)
THEN
347 WRITE (unit=output_unit, fmt=
"(/,T3,A,I4,A)") &
348 "# Integrating the xc kernel on the atomic grids ..."
354 do_os = xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks
356 IF (xas_tdp_control%do_xc .AND. (.NOT. xas_tdp_control%xps_only))
THEN
360 IF (xas_tdp_control%do_soc .OR. xas_tdp_control%do_gw2x)
THEN
368 IF ((.NOT. (xas_tdp_control%check_only .OR. xas_tdp_control%xps_only)) .AND. &
369 (xas_tdp_control%do_xc .OR. xas_tdp_control%do_coulomb))
THEN
370 IF (output_unit > 0)
THEN
371 WRITE (unit=output_unit, fmt=
"(/,T3,A,I4,A)") &
372 "# Computing the RI 3-center Coulomb integrals ..."
380 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
381 current_state_index = 1
384 DO ikind = 1,
SIZE(atomic_kind_set)
386 IF (xas_tdp_control%check_only)
EXIT
387 IF (.NOT. any(xas_tdp_env%ex_kind_indices == ikind)) cycle
389 CALL get_atomic_kind(atomic_kind=atomic_kind_set(ikind), name=kind_name, &
390 atom_list=atoms_of_kind)
394 IF (xas_tdp_control%do_hfx)
THEN
402 CALL get_ri_3c_batches(ex_atoms_of_kind, nbatch, batch_size, atoms_of_kind, xas_tdp_env)
403 nex_atom =
SIZE(ex_atoms_of_kind)
406 DO ibatch = 1, nbatch
408 bo =
get_limit(nex_atom, nbatch, ibatch - 1)
409 batch_size = bo(2) - bo(1) + 1
410 ALLOCATE (batch_atoms(batch_size))
412 DO iat = bo(1), bo(2)
414 batch_atoms(iatom) = ex_atoms_of_kind(iat)
419 IF (xas_tdp_control%do_hfx)
THEN
420 IF (output_unit > 0)
THEN
421 WRITE (unit=output_unit, fmt=
"(/,T3,A,I4,A,I4,A,I1,A,A)") &
422 "# Computing the RI 3-center Exchange integrals for batch ", ibatch,
"(/", nbatch,
") of ", &
423 batch_size,
" atoms of kind: ", trim(kind_name)
430 DO iat = 1, batch_size
431 iatom = batch_atoms(iat)
433 tmp_index =
locate(xas_tdp_env%ex_atom_indices, iatom)
437 IF (xas_tdp_control%dipole_form ==
xas_dip_len .OR. xas_tdp_control%do_quad)
THEN
438 CALL compute_lenrep_multipole(iatom, xas_tdp_env, xas_tdp_control, qs_env)
442 DO istate = 1,
SIZE(xas_tdp_env%state_types, 1)
444 IF (xas_tdp_env%state_types(istate, tmp_index) ==
xas_not_excited) cycle
446 current_state => xas_tdp_env%donor_states(current_state_index)
448 at_symbol=kind_name, kind_index=ikind, &
449 state_type=xas_tdp_env%state_types(istate, tmp_index))
452 IF (output_unit > 0)
THEN
453 WRITE (unit=output_unit, fmt=
"(/,T3,A,A2,A,I4,A,A,/)") &
454 "# Start of calculations for donor state of type ", &
455 xas_tdp_env%state_type_char(current_state%state_type),
" for atom", &
456 current_state%at_index,
" of kind ", trim(current_state%at_symbol)
461 CALL assign_mos_to_donor_state(current_state, xas_tdp_env, xas_tdp_control, qs_env)
464 CALL perform_mulliken_on_donor_state(current_state, qs_env)
467 IF (xas_tdp_control%do_gw2x)
THEN
468 CALL gw2x_shift(current_state, xas_tdp_env, xas_tdp_control, qs_env)
472 IF (.NOT. xas_tdp_control%xps_only)
THEN
475 IF (xas_tdp_control%do_spin_cons)
THEN
478 CALL compute_dipole_fosc(current_state, xas_tdp_control, xas_tdp_env)
479 IF (xas_tdp_control%do_quad)
CALL compute_quadrupole_fosc(current_state, &
480 xas_tdp_control, xas_tdp_env)
482 xas_tdp_section, qs_env)
483 CALL write_donor_state_restart(
tddfpt_spin_cons, current_state, xas_tdp_section, qs_env)
486 IF (xas_tdp_control%do_spin_flip)
THEN
491 xas_tdp_section, qs_env)
492 CALL write_donor_state_restart(
tddfpt_spin_flip, current_state, xas_tdp_section, qs_env)
495 IF (xas_tdp_control%do_singlet)
THEN
498 CALL compute_dipole_fosc(current_state, xas_tdp_control, xas_tdp_env)
499 IF (xas_tdp_control%do_quad)
CALL compute_quadrupole_fosc(current_state, &
500 xas_tdp_control, xas_tdp_env)
502 xas_tdp_section, qs_env)
503 CALL write_donor_state_restart(
tddfpt_singlet, current_state, xas_tdp_section, qs_env)
506 IF (xas_tdp_control%do_triplet)
THEN
511 xas_tdp_section, qs_env)
512 CALL write_donor_state_restart(
tddfpt_triplet, current_state, xas_tdp_section, qs_env)
516 IF (xas_tdp_control%do_soc .AND. current_state%state_type ==
xas_2p_type)
THEN
517 IF (xas_tdp_control%do_singlet .AND. xas_tdp_control%do_triplet)
THEN
518 CALL include_rcs_soc(current_state, xas_tdp_env, xas_tdp_control, qs_env)
520 IF (xas_tdp_control%do_spin_cons .AND. xas_tdp_control%do_spin_flip)
THEN
521 CALL include_os_soc(current_state, xas_tdp_env, xas_tdp_control, qs_env)
526 CALL print_xas_tdp_to_file(current_state, xas_tdp_env, xas_tdp_control, xas_tdp_section)
528 IF (xas_tdp_control%do_gw2x)
CALL print_xps(current_state, xas_tdp_env, xas_tdp_control, qs_env)
532 current_state_index = current_state_index + 1
533 NULLIFY (current_state)
537 end_of_batch = .false.
538 IF (iat == batch_size) end_of_batch = .true.
541 DEALLOCATE (batch_atoms)
543 DEALLOCATE (ex_atoms_of_kind)
547 IF (dft_control%do_admm)
THEN
548 CALL get_qs_env(qs_env, matrix_ks=matrix_ks, admm_env=admm_env)
549 DO ispin = 1, dft_control%nspins
555 IF (xas_tdp_control%eps_pgf > 0.0_dp)
THEN
556 CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set)
557 DO ikind = 1,
SIZE(atomic_kind_set)
558 CALL get_qs_kind(qs_kind_set(ikind), basis_set=tmp_basis, basis_type=
"ORB")
567 END SUBROUTINE xas_tdp_core
576 SUBROUTINE xas_tdp_init(xas_tdp_env, xas_tdp_control, qs_env, rixs_env)
583 CHARACTER(LEN=default_string_length) :: kind_name
584 INTEGER :: at_ind, i, ispin, j, k, kind_ind, &
585 n_donor_states, n_kinds, nao, &
586 nat_of_kind, natom, nex_atoms, &
587 nex_kinds, nmatch, nspins
588 INTEGER,
DIMENSION(2) :: homo, n_mo, n_moloc
589 INTEGER,
DIMENSION(:),
POINTER :: ind_of_kind
590 LOGICAL :: do_os, do_rixs, do_uks, unique
592 REAL(
dp),
DIMENSION(:),
POINTER :: mo_evals
597 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_ks, matrix_s, rho_ao
603 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
609 NULLIFY (xas_tdp_section, at_kind_set, ind_of_kind, dft_control, qs_kind_set, tmp_basis)
610 NULLIFY (qs_loc_env, loc_section, mos, particle_set, rho, rho_ao, mo_evals, cell)
611 NULLIFY (mo_coeff, matrix_ks, admm_env, dummy_section)
614 CALL get_qs_env(qs_env, dft_control=dft_control, do_rixs=do_rixs)
626 IF (dft_control%uks) xas_tdp_control%do_uks = .true.
627 IF (dft_control%roks) xas_tdp_control%do_roks = .true.
628 do_uks = xas_tdp_control%do_uks
629 do_os = do_uks .OR. xas_tdp_control%do_roks
632 IF (
PRESENT(rixs_env))
THEN
633 xas_tdp_env => rixs_env%core_state
642 nex_atoms =
SIZE(xas_tdp_control%list_ex_atoms)
644 ALLOCATE (xas_tdp_env%ex_atom_indices(nex_atoms))
645 ALLOCATE (xas_tdp_env%state_types(
SIZE(xas_tdp_control%state_types, 1), nex_atoms))
646 xas_tdp_env%ex_atom_indices = xas_tdp_control%list_ex_atoms
647 xas_tdp_env%state_types = xas_tdp_control%state_types
651 IF (any(xas_tdp_env%ex_atom_indices > natom))
THEN
652 cpabort(
"Invalid index for the ATOM_LIST keyword.")
656 ALLOCATE (xas_tdp_env%ex_kind_indices(nex_atoms))
657 xas_tdp_env%ex_kind_indices = 0
659 CALL get_qs_env(qs_env, particle_set=particle_set)
661 at_ind = xas_tdp_env%ex_atom_indices(i)
663 IF (all(abs(xas_tdp_env%ex_kind_indices - j) /= 0))
THEN
665 xas_tdp_env%ex_kind_indices(k) = j
670 CALL reallocate(xas_tdp_env%ex_kind_indices, 1, nex_kinds)
675 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=at_kind_set)
676 n_kinds =
SIZE(at_kind_set)
679 nex_kinds =
SIZE(xas_tdp_control%list_ex_kinds)
680 ALLOCATE (xas_tdp_env%ex_kind_indices(nex_kinds))
685 natom=nat_of_kind, kind_number=kind_ind)
686 IF (any(xas_tdp_control%list_ex_kinds == kind_name))
THEN
687 nex_atoms = nex_atoms + nat_of_kind
689 xas_tdp_env%ex_kind_indices(k) = kind_ind
693 ALLOCATE (xas_tdp_env%ex_atom_indices(nex_atoms))
694 ALLOCATE (xas_tdp_env%state_types(
SIZE(xas_tdp_control%state_types, 1), nex_atoms))
700 natom=nat_of_kind, atom_list=ind_of_kind)
702 IF (xas_tdp_control%list_ex_kinds(j) == kind_name)
THEN
703 xas_tdp_env%ex_atom_indices(nex_atoms + 1:nex_atoms + nat_of_kind) = ind_of_kind
704 DO k = 1,
SIZE(xas_tdp_control%state_types, 1)
705 xas_tdp_env%state_types(k, nex_atoms + 1:nex_atoms + nat_of_kind) = &
706 xas_tdp_control%state_types(k, j)
708 nex_atoms = nex_atoms + nat_of_kind
714 CALL set_xas_tdp_env(xas_tdp_env, nex_atoms=nex_atoms, nex_kinds=nex_kinds)
717 IF (nmatch /=
SIZE(xas_tdp_control%list_ex_kinds))
THEN
718 cpabort(
"Invalid kind(s) for the KIND_LIST keyword.")
724 CALL sort_unique(xas_tdp_env%ex_atom_indices, unique)
725 IF (.NOT. unique)
THEN
726 cpabort(
"Excited atoms not uniquely defined.")
731 IF (all(cell%perd == 0))
THEN
732 xas_tdp_control%is_periodic = .false.
733 ELSE IF (all(cell%perd == 1))
THEN
734 xas_tdp_control%is_periodic = .true.
736 cpabort(
"XAS TDP only implemented for full PBCs or non-PBCs")
741 ALLOCATE (xas_tdp_env%donor_states(n_donor_states))
742 DO i = 1, n_donor_states
747 IF (dft_control%do_admm)
THEN
748 CALL get_qs_env(qs_env, admm_env=admm_env, matrix_ks=matrix_ks)
750 DO ispin = 1, dft_control%nspins
756 IF (xas_tdp_control%eps_pgf > 0.0_dp)
THEN
757 CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set)
759 DO i = 1,
SIZE(qs_kind_set)
760 CALL get_qs_kind(qs_kind_set(i), basis_set=tmp_basis, basis_type=
"ORB")
762 CALL get_qs_kind(qs_kind_set(i), basis_set=tmp_basis, basis_type=
"RI_XAS")
770 CALL get_qs_env(qs_env, mos=mos, matrix_ks=matrix_ks)
771 nspins = 1;
IF (do_uks) nspins = 2
774 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, eigenvalues=mo_evals)
784 l_val=xas_tdp_control%do_loc)
787 xas_tdp_control%loc_subsection,
"PRINT")
789 ALLOCATE (xas_tdp_env%qs_loc_env)
791 qs_loc_env => xas_tdp_env%qs_loc_env
792 loc_section => xas_tdp_control%loc_subsection
795 CALL get_mo_set(mos(1), nmo=n_mo(1), homo=homo(1), nao=nao)
799 IF (do_os)
CALL get_mo_set(mos(2), nmo=n_mo(2), homo=homo(2))
800 IF (do_uks) nspins = 2
803 IF (xas_tdp_control%n_search < 0 .OR. xas_tdp_control%n_search > minval(homo)) &
804 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, rho=rho, matrix_s=matrix_s)
841 ALLOCATE (xas_tdp_env%q_projector(nspins))
842 ALLOCATE (xas_tdp_env%q_projector(1)%matrix)
843 CALL dbcsr_create(xas_tdp_env%q_projector(1)%matrix, name=
"Q PROJECTOR ALPHA", &
844 template=matrix_s(1)%matrix, matrix_type=dbcsr_type_no_symmetry)
846 ALLOCATE (xas_tdp_env%q_projector(2)%matrix)
847 CALL dbcsr_create(xas_tdp_env%q_projector(2)%matrix, name=
"Q PROJECTOR BETA", &
848 template=matrix_s(1)%matrix, matrix_type=dbcsr_type_no_symmetry)
852 fact = -0.5_dp;
IF (do_os) fact = -1.0_dp
853 CALL dbcsr_multiply(
'N',
'N', fact, matrix_s(1)%matrix, rho_ao(1)%matrix, 0.0_dp, &
854 xas_tdp_env%q_projector(1)%matrix, filter_eps=xas_tdp_control%eps_filter)
859 CALL dbcsr_multiply(
'N',
'N', fact, matrix_s(1)%matrix, rho_ao(2)%matrix, 0.0_dp, &
860 xas_tdp_env%q_projector(2)%matrix, filter_eps=xas_tdp_control%eps_filter)
866 ALLOCATE (xas_tdp_env%dipmat(3))
868 ALLOCATE (xas_tdp_env%dipmat(i)%matrix)
869 CALL dbcsr_copy(matrix_tmp, matrix_s(1)%matrix, name=
"XAS TDP dipole matrix")
870 IF (xas_tdp_control%dipole_form ==
xas_dip_vel)
THEN
871 CALL dbcsr_create(xas_tdp_env%dipmat(i)%matrix, template=matrix_s(1)%matrix, &
872 matrix_type=dbcsr_type_antisymmetric)
875 CALL dbcsr_create(xas_tdp_env%dipmat(i)%matrix, template=matrix_s(1)%matrix, &
876 matrix_type=dbcsr_type_symmetric)
877 CALL dbcsr_copy(xas_tdp_env%dipmat(i)%matrix, matrix_tmp)
879 CALL dbcsr_set(xas_tdp_env%dipmat(i)%matrix, 0.0_dp)
884 IF (xas_tdp_control%do_quad)
THEN
885 ALLOCATE (xas_tdp_env%quadmat(6))
887 ALLOCATE (xas_tdp_env%quadmat(i)%matrix)
888 CALL dbcsr_copy(xas_tdp_env%quadmat(i)%matrix, matrix_s(1)%matrix, name=
"XAS TDP quadrupole matrix")
889 CALL dbcsr_set(xas_tdp_env%quadmat(i)%matrix, 0.0_dp)
894 IF (xas_tdp_control%dipole_form ==
xas_dip_vel)
THEN
896 CALL p_xyz_ao(xas_tdp_env%dipmat, qs_env, minimum_image=.true.)
900 IF (xas_tdp_control%do_soc .OR. xas_tdp_control%do_gw2x)
THEN
901 ALLOCATE (xas_tdp_env%orb_soc(3))
903 ALLOCATE (xas_tdp_env%orb_soc(i)%matrix)
908 CALL safety_check(xas_tdp_control, qs_env)
914 IF (xas_tdp_control%do_ot .OR. xas_tdp_control%do_gw2x)
THEN
915 CALL make_lumo_guess(xas_tdp_env, xas_tdp_control, qs_env)
928 SUBROUTINE get_ri_3c_batches(ex_atoms_of_kind, nbatch, batch_size, atoms_of_kind, xas_tdp_env)
930 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(INOUT) :: ex_atoms_of_kind
931 INTEGER,
INTENT(OUT) :: nbatch
932 INTEGER,
INTENT(IN) :: batch_size
933 INTEGER,
DIMENSION(:),
INTENT(IN) :: atoms_of_kind
936 INTEGER :: iat, iatom, nex_atom
941 DO iat = 1,
SIZE(atoms_of_kind)
942 iatom = atoms_of_kind(iat)
943 IF (.NOT. any(xas_tdp_env%ex_atom_indices == iatom)) cycle
944 nex_atom = nex_atom + 1
947 ALLOCATE (ex_atoms_of_kind(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
953 ex_atoms_of_kind(nex_atom) = iatom
958 CALL rng_stream%shuffle(ex_atoms_of_kind(1:nex_atom))
960 nbatch = nex_atom/batch_size
961 IF (nbatch*batch_size /= nex_atom) nbatch = nbatch + 1
963 END SUBROUTINE get_ri_3c_batches
970 SUBROUTINE safety_check(xas_tdp_control, qs_env)
978 IF (xas_tdp_control%is_periodic .AND. xas_tdp_control%do_hfx &
980 cpabort(
"XAS TDP with Coulomb operator for exact exchange only supports non-periodic BCs")
984 IF (xas_tdp_control%do_roks .OR. xas_tdp_control%do_uks)
THEN
986 IF (.NOT. (xas_tdp_control%do_spin_cons .OR. xas_tdp_control%do_spin_flip))
THEN
987 cpabort(
"Need spin-conserving and/or spin-flip excitations for open-shell systems")
990 IF (xas_tdp_control%do_singlet .OR. xas_tdp_control%do_triplet)
THEN
991 cpabort(
"Singlet/triplet excitations only for restricted closed-shell systems")
994 IF (xas_tdp_control%do_soc .AND. .NOT. &
995 (xas_tdp_control%do_spin_flip .AND. xas_tdp_control%do_spin_cons))
THEN
997 cpabort(
"Both spin-conserving and spin-flip excitations are required for SOC")
1001 IF (.NOT. (xas_tdp_control%do_singlet .OR. xas_tdp_control%do_triplet))
THEN
1002 cpabort(
"Need singlet and/or triplet excitations for closed-shell systems")
1005 IF (xas_tdp_control%do_spin_cons .OR. xas_tdp_control%do_spin_flip)
THEN
1006 cpabort(
"Spin-conserving/spin-flip excitations only for open-shell systems")
1009 IF (xas_tdp_control%do_soc .AND. .NOT. &
1010 (xas_tdp_control%do_singlet .AND. xas_tdp_control%do_triplet))
THEN
1012 cpabort(
"Both singlet and triplet excitations are needed for SOC")
1017 IF (xas_tdp_control%do_soc .AND. xas_tdp_control%e_range > 0.0_dp)
THEN
1018 cpwarn(
"Using E_RANGE and SOC together may lead to crashes, use N_EXCITED for safety.")
1022 IF (.NOT. xas_tdp_control%tamm_dancoff)
THEN
1024 IF (xas_tdp_control%do_spin_flip)
THEN
1025 cpabort(
"Spin-flip kernel only implemented for Tamm-Dancoff approximation")
1028 IF (xas_tdp_control%do_ot)
THEN
1029 cpabort(
"OT diagonalization only available within the Tamm-Dancoff approximation")
1034 IF (xas_tdp_control%do_gw2x)
THEN
1035 IF (.NOT. xas_tdp_control%do_hfx)
THEN
1036 cpabort(
"GW2x requires the definition of the EXACT_EXCHANGE kernel")
1038 IF (.NOT. xas_tdp_control%do_loc)
THEN
1039 cpabort(
"GW2X requires the LOCALIZE keyword in DONOR_STATES")
1044 CALL get_qs_env(qs_env, dft_control=dft_control)
1045 IF (dft_control%do_admm)
THEN
1050 cpabort(
"XAS_TDP only compatible with ADMM purification NONE, CAUCHY_SUBSPACE and MO_DIAG")
1055 END SUBROUTINE safety_check
1063 SUBROUTINE print_info(ou, xas_tdp_control, qs_env)
1065 INTEGER,
INTENT(IN) :: ou
1075 NULLIFY (input, kernel_section, dft_control, matrix_s)
1077 CALL get_qs_env(qs_env, input=input, dft_control=dft_control, matrix_s=matrix_s)
1085 IF (xas_tdp_control%do_uks)
THEN
1086 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1087 "XAS_TDP| Reference calculation: Unrestricted Kohn-Sham"
1088 ELSE IF (xas_tdp_control%do_roks)
THEN
1089 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1090 "XAS_TDP| Reference calculation: Restricted Open-Shell Kohn-Sham"
1092 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1093 "XAS_TDP| Reference calculation: Restricted Closed-Shell Kohn-Sham"
1097 IF (xas_tdp_control%tamm_dancoff)
THEN
1098 WRITE (unit=ou, fmt=
"(T3,A)") &
1099 "XAS_TDP| Tamm-Dancoff Approximation (TDA): On"
1101 WRITE (unit=ou, fmt=
"(T3,A)") &
1102 "XAS_TDP| Tamm-Dancoff Approximation (TDA): Off"
1106 IF (xas_tdp_control%dipole_form ==
xas_dip_vel)
THEN
1107 WRITE (unit=ou, fmt=
"(T3,A)") &
1108 "XAS_TDP| Transition Dipole Representation: VELOCITY"
1110 WRITE (unit=ou, fmt=
"(T3,A)") &
1111 "XAS_TDP| Transition Dipole Representation: LENGTH"
1115 IF (xas_tdp_control%do_quad)
THEN
1116 WRITE (unit=ou, fmt=
"(T3,A)") &
1117 "XAS_TDP| Transition Quadrupole: On"
1121 IF (xas_tdp_control%eps_pgf > 0.0_dp)
THEN
1122 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1123 "XAS_TDP| EPS_PGF_XAS: ", xas_tdp_control%eps_pgf
1125 WRITE (unit=ou, fmt=
"(T3,A,ES7.1,A)") &
1126 "XAS_TDP| EPS_PGF_XAS: ", dft_control%qs_control%eps_pgf_orb,
" (= EPS_PGF_ORB)"
1130 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1131 "XAS_TDP| EPS_FILTER: ", xas_tdp_control%eps_filter
1134 IF (xas_tdp_control%do_xc)
THEN
1135 WRITE (unit=ou, fmt=
"(T3,A)") &
1136 "XAS_TDP| Radial Grid(s) Info: Kind, na, nr"
1137 DO i = 1,
SIZE(xas_tdp_control%grid_info, 1)
1138 WRITE (unit=ou, fmt=
"(T3,A,A6,A,A,A,A)") &
1139 " ", trim(xas_tdp_control%grid_info(i, 1)),
", ", &
1140 trim(xas_tdp_control%grid_info(i, 2)),
", ", trim(xas_tdp_control%grid_info(i, 3))
1145 IF (.NOT. xas_tdp_control%do_coulomb)
THEN
1146 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1147 "XAS_TDP| No kernel (standard DFT)"
1151 IF (xas_tdp_control%do_xc)
THEN
1153 WRITE (unit=ou, fmt=
"(/,T3,A,F5.2,A)") &
1154 "XAS_TDP| RI Region's Radius: ", xas_tdp_control%ri_radius*
angstrom,
" Ang"
1156 WRITE (unit=ou, fmt=
"(T3,A,/)") &
1157 "XAS_TDP| XC Kernel Functional(s) used for the kernel:"
1159 IF (qs_env%do_rixs)
THEN
1164 CALL xc_write(ou, kernel_section, lsd=.true.)
1168 IF (xas_tdp_control%do_hfx)
THEN
1169 WRITE (unit=ou, fmt=
"(/,T3,A,/,/,T3,A,F5.3)") &
1170 "XAS_TDP| Exact Exchange Kernel: Yes ", &
1171 "EXACT_EXCHANGE| Scale: ", xas_tdp_control%sx
1173 WRITE (unit=ou, fmt=
"(T3,A)") &
1174 "EXACT_EXCHANGE| Potential : Coulomb"
1176 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,A)") &
1177 "EXACT_EXCHANGE| Potential: Truncated Coulomb", &
1178 "EXACT_EXCHANGE| Range: ", xas_tdp_control%x_potential%cutoff_radius*
angstrom,
", (Ang)", &
1179 "EXACT_EXCHANGE| T_C_G_DATA: ", trim(xas_tdp_control%x_potential%filename)
1181 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,F5.2,A,/,T3,A,ES7.1)") &
1182 "EXACT_EXCHANGE| Potential: Short Range", &
1183 "EXACT_EXCHANGE| Omega: ", xas_tdp_control%x_potential%omega,
", (1/a0)", &
1184 "EXACT_EXCHANGE| Effective Range: ", xas_tdp_control%x_potential%cutoff_radius*
angstrom,
", (Ang)", &
1185 "EXACT_EXCHANGE| EPS_RANGE: ", xas_tdp_control%eps_range
1187 IF (xas_tdp_control%eps_screen > 1.0e-16)
THEN
1188 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1189 "EXACT_EXCHANGE| EPS_SCREENING: ", xas_tdp_control%eps_screen
1193 IF (xas_tdp_control%do_ri_metric)
THEN
1195 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1196 "EXACT_EXCHANGE| Using a RI metric"
1197 IF (xas_tdp_control%ri_m_potential%potential_type ==
do_potential_id)
THEN
1198 WRITE (unit=ou, fmt=
"(T3,A)") &
1199 "EXACT_EXCHANGE RI_METRIC| Potential : Overlap"
1201 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,A)") &
1202 "EXACT_EXCHANGE RI_METRIC| Potential: Truncated Coulomb", &
1203 "EXACT_EXCHANGE RI_METRIC| Range: ", xas_tdp_control%ri_m_potential%cutoff_radius &
1205 "EXACT_EXCHANGE RI_METRIC| T_C_G_DATA: ", trim(xas_tdp_control%ri_m_potential%filename)
1207 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,F5.2,A,/,T3,A,ES7.1)") &
1208 "EXACT_EXCHANGE RI_METRIC| Potential: Short Range", &
1209 "EXACT_EXCHANGE RI_METRIC| Omega: ", xas_tdp_control%ri_m_potential%omega,
", (1/a0)", &
1210 "EXACT_EXCHANGE RI_METRIC| Effective Range: ", &
1211 xas_tdp_control%ri_m_potential%cutoff_radius*
angstrom,
", (Ang)", &
1212 "EXACT_EXCHANGE RI_METRIC| EPS_RANGE: ", xas_tdp_control%eps_range
1216 WRITE (unit=ou, fmt=
"(/,T3,A,/)") &
1217 "XAS_TDP| Exact Exchange Kernel: No "
1221 WRITE (unit=ou, fmt=
"(/,T3,A,F5.2)") &
1222 "XAS_TDP| Overlap matrix occupation: ", occ
1225 IF (xas_tdp_control%do_gw2x)
THEN
1226 WRITE (unit=ou, fmt=
"(T3,A,/)") &
1227 "XAS_TDP| GW2X correction enabled"
1229 IF (xas_tdp_control%xps_only)
THEN
1230 WRITE (unit=ou, fmt=
"(T3,A)") &
1231 "GW2X| Only computing ionizations potentials for XPS"
1234 IF (xas_tdp_control%pseudo_canonical)
THEN
1235 WRITE (unit=ou, fmt=
"(T3,A)") &
1236 "GW2X| Using the pseudo-canonical scheme"
1238 WRITE (unit=ou, fmt=
"(T3,A)") &
1239 "GW2X| Using the GW2X* scheme"
1242 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1243 "GW2X| EPS_GW2X: ", xas_tdp_control%gw2x_eps
1245 WRITE (unit=ou, fmt=
"(T3,A,I5)") &
1246 "GW2X| contraction batch size: ", xas_tdp_control%batch_size
1248 IF ((int(xas_tdp_control%c_os) /= 1) .OR. (int(xas_tdp_control%c_ss) /= 1))
THEN
1249 WRITE (unit=ou, fmt=
"(T3,A,F7.4,/,T3,A,F7.4)") &
1250 "GW2X| Same-spin scaling factor: ", xas_tdp_control%c_ss, &
1251 "GW2X| Opposite-spin scaling factor: ", xas_tdp_control%c_os
1256 END SUBROUTINE print_info
1271 SUBROUTINE assign_mos_to_ex_atoms(xas_tdp_env, xas_tdp_control, qs_env)
1277 INTEGER :: at_index, iat, iat_memo, imo, ispin, &
1278 n_atoms, n_search, nex_atoms, nspins
1279 INTEGER,
DIMENSION(3) :: perd_init
1280 INTEGER,
DIMENSION(:, :, :),
POINTER :: mos_of_ex_atoms
1281 REAL(
dp) :: dist, dist_min
1282 REAL(
dp),
DIMENSION(3) :: at_pos, r_ac, wfn_center
1287 NULLIFY (localized_wfn_control, mos_of_ex_atoms, cell, particle_set)
1290 mos_of_ex_atoms => xas_tdp_env%mos_of_ex_atoms
1291 mos_of_ex_atoms(:, :, :) = -1
1292 n_search = xas_tdp_control%n_search
1293 nex_atoms = xas_tdp_env%nex_atoms
1294 localized_wfn_control => xas_tdp_env%qs_loc_env%localized_wfn_control
1295 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, cell=cell)
1296 n_atoms =
SIZE(particle_set)
1297 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1300 perd_init = cell%perd
1304 DO ispin = 1, nspins
1305 DO imo = 1, n_search
1307 wfn_center(1:3) = localized_wfn_control%centers_set(ispin)%array(1:3, imo)
1311 dist_min = 10000.0_dp
1313 at_pos = particle_set(iat)%r
1314 r_ac =
pbc(at_pos, wfn_center, cell)
1318 IF (dist < dist_min)
THEN
1325 IF (any(xas_tdp_env%ex_atom_indices == iat_memo))
THEN
1326 at_index =
locate(xas_tdp_env%ex_atom_indices, iat_memo)
1327 mos_of_ex_atoms(imo, at_index, ispin) = 1
1333 cell%perd = perd_init
1335 END SUBROUTINE assign_mos_to_ex_atoms
1347 SUBROUTINE reinit_qs_loc_env(qs_loc_env, n_loc_states, do_uks, qs_env)
1350 INTEGER,
INTENT(IN) :: n_loc_states
1351 LOGICAL,
INTENT(IN) :: do_uks
1354 INTEGER :: i, nspins
1363 loc_wfn_control => qs_loc_env%localized_wfn_control
1368 loc_wfn_control%nloc_states(:) = n_loc_states
1369 loc_wfn_control%eps_occ = 0.0_dp
1370 loc_wfn_control%lu_bound_states(1, :) = 1
1371 loc_wfn_control%lu_bound_states(2, :) = n_loc_states
1373 loc_wfn_control%do_homo = .true.
1374 ALLOCATE (loc_wfn_control%loc_states(n_loc_states, 2))
1375 DO i = 1, n_loc_states
1376 loc_wfn_control%loc_states(i, :) = i
1379 nspins = 1;
IF (do_uks) nspins = 2
1380 CALL set_loc_centers(loc_wfn_control, loc_wfn_control%nloc_states, nspins=nspins)
1383 CALL qs_loc_env_init(qs_loc_env, loc_wfn_control, qs_env, do_localize=.true.)
1385 CALL qs_loc_env_init(qs_loc_env, loc_wfn_control, qs_env, myspin=1, do_localize=.true.)
1388 END SUBROUTINE reinit_qs_loc_env
1398 SUBROUTINE diagonalize_assigned_mo_subset(xas_tdp_env, xas_tdp_control, qs_env)
1404 INTEGER :: i, iat, ilmo, ispin, nao, nlmo, nspins
1405 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: evals
1408 TYPE(
cp_fm_type) :: evecs, ks_fm, lmo_fm, work
1414 NULLIFY (mos, mo_coeff, matrix_ks, para_env, blacs_env, lmo_struct, ks_struct)
1417 CALL get_qs_env(qs_env, mos=mos, matrix_ks=matrix_ks, para_env=para_env, blacs_env=blacs_env)
1419 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1422 DO ispin = 1, nspins
1423 DO iat = 1, xas_tdp_env%nex_atoms
1426 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, nao=nao)
1429 nlmo = count(xas_tdp_env%mos_of_ex_atoms(:, iat, ispin) == 1)
1431 para_env=para_env, context=blacs_env)
1436 para_env=para_env, context=blacs_env)
1442 DO ilmo = 1, xas_tdp_control%n_search
1443 IF (xas_tdp_env%mos_of_ex_atoms(ilmo, iat, ispin) == -1) cycle
1448 s_firstcol=ilmo, t_firstrow=1, t_firstcol=i)
1454 CALL parallel_gemm(
'T',
'N', nlmo, nlmo, nao, 1.0_dp, lmo_fm, work, 0.0_dp, ks_fm)
1457 ALLOCATE (evals(nlmo))
1462 CALL parallel_gemm(
'N',
'N', nao, nlmo, nlmo, 1.0_dp, lmo_fm, evecs, 0.0_dp, work)
1466 DO ilmo = 1, xas_tdp_control%n_search
1467 IF (xas_tdp_env%mos_of_ex_atoms(ilmo, iat, ispin) == -1) cycle
1471 s_firstcol=i, t_firstrow=1, t_firstcol=ilmo)
1485 END SUBROUTINE diagonalize_assigned_mo_subset
1496 SUBROUTINE assign_mos_to_donor_state(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
1503 INTEGER :: at_index, i, iat, imo, ispin, l, my_mo, &
1504 n_search, n_states, nao, ndo_so, nj, &
1505 nsgf_kind, nsgf_sto, nspins, &
1507 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: my_mos
1508 INTEGER,
DIMENSION(2) :: next_best_overlap_ind
1509 INTEGER,
DIMENSION(4, 7) :: ne
1510 INTEGER,
DIMENSION(:),
POINTER :: first_sgf, lq, nq
1511 INTEGER,
DIMENSION(:, :, :),
POINTER :: mos_of_ex_atoms
1514 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) ::
diag, overlap, sto_overlap
1515 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: max_overlap
1516 REAL(
dp),
DIMENSION(2) :: next_best_overlap
1517 REAL(
dp),
DIMENSION(:),
POINTER :: mo_evals, zeta
1518 REAL(
dp),
DIMENSION(:, :),
POINTER :: overlap_matrix, tmp_coeff
1522 TYPE(
cp_fm_type),
POINTER :: gs_coeffs, mo_coeff
1528 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
1531 NULLIFY (sto_basis_set, sto_to_gto_basis_set, qs_kind_set, kind_basis_set, lq, nq, zeta)
1532 NULLIFY (overlap_matrix, mos, mo_coeff, mos_of_ex_atoms, tmp_coeff, first_sgf, particle_set)
1533 NULLIFY (mo_evals, matrix_ks, para_env, blacs_env)
1534 NULLIFY (eval_mat_struct, gs_struct, gs_coeffs)
1538 CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set, mos=mos, particle_set=particle_set, &
1539 matrix_ks=matrix_ks, para_env=para_env, blacs_env=blacs_env)
1541 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1552 ELSE IF (donor_state%state_type ==
xas_2s_type)
THEN
1556 ELSE IF (donor_state%state_type ==
xas_2p_type)
THEN
1561 cpabort(
"Procedure for required type not implemented")
1563 ALLOCATE (my_mos(n_states, nspins))
1564 ALLOCATE (max_overlap(n_states, nspins))
1567 CALL get_qs_kind(qs_kind_set(donor_state%kind_index), zeff=zeff)
1575 ne(l, i) =
ptable(zval)%e_conv(l - 1) - 2*nj*(i - l)
1576 ne(l, i) = max(ne(l, i), 0)
1577 ne(l, i) = min(ne(l, i), 2*nj)
1582 zeta(1) =
srules(zval, ne, nq(1), lq(1))
1589 DEALLOCATE (nq, lq, zeta)
1593 gto_basis_set=sto_to_gto_basis_set, &
1595 sto_to_gto_basis_set%norm_type = 2
1599 CALL get_qs_kind(qs_kind_set(donor_state%kind_index), basis_set=kind_basis_set)
1604 ALLOCATE (overlap_matrix(nsgf_sto, nsgf_kind))
1614 mos_of_ex_atoms => xas_tdp_env%mos_of_ex_atoms
1615 n_search = xas_tdp_control%n_search
1616 at_index = donor_state%at_index
1617 iat =
locate(xas_tdp_env%ex_atom_indices, at_index)
1618 ALLOCATE (first_sgf(
SIZE(particle_set)))
1619 CALL get_particle_set(particle_set=particle_set, qs_kind_set=qs_kind_set, first_sgf=first_sgf)
1620 ALLOCATE (tmp_coeff(nsgf_kind, 1))
1621 ALLOCATE (sto_overlap(nsgf_kind))
1622 ALLOCATE (overlap(n_search))
1624 next_best_overlap = 0.0_dp
1625 max_overlap = 0.0_dp
1627 DO ispin = 1, nspins
1629 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, nao=nao)
1633 DO imo = 1, n_search
1634 IF (mos_of_ex_atoms(imo, iat, ispin) > 0)
THEN
1636 sto_overlap = 0.0_dp
1640 CALL cp_fm_get_submatrix(fm=mo_coeff, target_m=tmp_coeff, start_row=first_sgf(at_index), &
1641 start_col=imo, n_rows=nsgf_kind, n_cols=1, transpose=.false.)
1644 CALL dgemm(
'N',
'N', nsgf_sto, 1, nsgf_kind, 1.0_dp, overlap_matrix, nsgf_sto, &
1645 tmp_coeff, nsgf_kind, 0.0_dp, sto_overlap, nsgf_sto)
1650 overlap(imo) = sum(abs(sto_overlap))
1657 my_mo = maxloc(overlap, 1)
1658 my_mos(i, ispin) = my_mo
1659 max_overlap(i, ispin) = maxval(overlap, 1)
1660 overlap(my_mo) = 0.0_dp
1663 next_best_overlap(ispin) = maxval(overlap, 1)
1664 next_best_overlap_ind(ispin) = maxloc(overlap, 1)
1672 DEALLOCATE (overlap_matrix, tmp_coeff)
1675 IF (all(my_mos > 0) .AND. all(my_mos <= n_search))
THEN
1677 ALLOCATE (donor_state%mo_indices(n_states, nspins))
1678 donor_state%mo_indices = my_mos
1679 donor_state%ndo_mo = n_states
1683 para_env=para_env, context=blacs_env)
1684 ALLOCATE (donor_state%gs_coeffs)
1687 IF (.NOT.
ASSOCIATED(xas_tdp_env%mo_coeff))
THEN
1688 ALLOCATE (xas_tdp_env%mo_coeff(nspins))
1691 DO ispin = 1, nspins
1692 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff)
1694 IF (.NOT.
ASSOCIATED(xas_tdp_env%mo_coeff(ispin)%local_data))
THEN
1697 matrix_struct=matrix_struct)
1698 CALL cp_fm_create(xas_tdp_env%mo_coeff(ispin), matrix_struct)
1699 CALL cp_fm_to_fm(mo_coeff, xas_tdp_env%mo_coeff(ispin))
1704 ncol=1, s_firstrow=1, s_firstcol=my_mos(i, ispin), &
1705 t_firstrow=1, t_firstcol=(ispin - 1)*n_states + i)
1708 gs_coeffs => donor_state%gs_coeffs
1711 ALLOCATE (donor_state%contract_coeffs(nsgf_kind, n_states*nspins))
1712 CALL cp_fm_get_submatrix(gs_coeffs, donor_state%contract_coeffs, start_row=first_sgf(at_index), &
1713 start_col=1, n_rows=nsgf_kind, n_cols=n_states*nspins)
1718 IF (.NOT. xas_tdp_control%do_loc .AND. .NOT. xas_tdp_control%do_roks)
THEN
1719 IF (output_unit > 0)
THEN
1720 WRITE (unit=output_unit, fmt=
"(T5,A,/,T5,A,/,T5,A)") &
1721 "The following canonical MO(s) have been associated with the donor state(s)", &
1722 "based on the overlap with the components of a minimal STO basis: ", &
1723 " Spin MO index overlap(sum)"
1726 ALLOCATE (donor_state%energy_evals(n_states, nspins))
1727 donor_state%energy_evals = 0.0_dp
1730 DO ispin = 1, nspins
1731 CALL get_mo_set(mos(ispin), eigenvalues=mo_evals)
1733 donor_state%energy_evals(i, ispin) = mo_evals(my_mos(i, ispin))
1735 IF (output_unit > 0)
THEN
1736 WRITE (unit=output_unit, fmt=
"(T46,I4,I11,F17.5)") &
1737 ispin, my_mos(i, ispin), max_overlap(i, ispin)
1745 IF (output_unit > 0)
THEN
1746 WRITE (unit=output_unit, fmt=
"(T5,A,/,T5,A,/,T5,A)") &
1747 "The following localized MO(s) have been associated with the donor state(s)", &
1748 "based on the overlap with the components of a minimal STO basis: ", &
1749 " Spin MO index overlap(sum)"
1753 DO ispin = 1, nspins
1757 IF (output_unit > 0)
THEN
1758 WRITE (unit=output_unit, fmt=
"(T46,I4,I11,F17.5)") &
1759 ispin, my_mos(i, ispin), max_overlap(i, ispin)
1767 ndo_so = nspins*n_states
1770 para_env=para_env, context=blacs_env)
1772 ALLOCATE (
diag(ndo_so))
1774 IF (.NOT. xas_tdp_control%do_roks)
THEN
1776 ALLOCATE (donor_state%energy_evals(n_states, nspins))
1777 donor_state%energy_evals = 0.0_dp
1780 DO ispin = 1, nspins
1782 CALL parallel_gemm(
'T',
'N', ndo_so, ndo_so, nao, 1.0_dp, gs_coeffs, work_mat, 0.0_dp, eval_mat)
1786 donor_state%energy_evals(:, ispin) =
diag((ispin - 1)*n_states + 1:ispin*n_states)
1792 ALLOCATE (donor_state%energy_evals(n_states, 2))
1793 donor_state%energy_evals = 0.0_dp
1798 CALL parallel_gemm(
'T',
'N', ndo_so, ndo_so, nao, 1.0_dp, gs_coeffs, work_mat, 0.0_dp, eval_mat)
1801 donor_state%energy_evals(:, ispin) =
diag(:)
1816 ALLOCATE (donor_state%gw2x_evals(
SIZE(donor_state%energy_evals, 1),
SIZE(donor_state%energy_evals, 2)))
1817 donor_state%gw2x_evals(:, :) = donor_state%energy_evals(:, :)
1821 DEALLOCATE (first_sgf)
1823 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T5,A)")
" "
1825 DO ispin = 1, nspins
1826 IF (output_unit > 0)
THEN
1827 WRITE (unit=output_unit, fmt=
"(T5,A,I1,A,F7.5,A,I4)") &
1828 "The next best overlap for spin ", ispin,
" is ", next_best_overlap(ispin), &
1829 " for MO with index ", next_best_overlap_ind(ispin)
1832 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T5,A)")
" "
1835 cpabort(
"A core donor state could not be assigned MO(s). Increasing NSEARCH might help.")
1838 END SUBROUTINE assign_mos_to_donor_state
1848 SUBROUTINE find_mo_centers(xas_tdp_env, xas_tdp_control, qs_env)
1854 INTEGER :: dim_op, i, ispin, j, n_centers, nao, &
1856 REAL(
dp),
DIMENSION(6) :: weights
1861 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:, :) :: zij_fm_set
1862 TYPE(
cp_fm_type),
DIMENSION(:),
POINTER :: moloc_coeff
1864 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: op_sm_set
1869 NULLIFY (qs_loc_env, cell, print_loc_section, op_sm_set, moloc_coeff, vectors)
1870 NULLIFY (tmp_fm_struct, para_env, blacs_env, prog_run_info)
1873 print_loc_section => xas_tdp_control%print_loc_subsection
1874 n_centers = xas_tdp_control%n_search
1875 CALL get_qs_env(qs_env=qs_env, para_env=para_env, blacs_env=blacs_env, cell=cell)
1883 CALL reinit_qs_loc_env(xas_tdp_env%qs_loc_env, n_centers, xas_tdp_control%do_uks, qs_env)
1884 qs_loc_env => xas_tdp_env%qs_loc_env
1887 CALL get_qs_loc_env(qs_loc_env=qs_loc_env, weights=weights, op_sm_set=op_sm_set, &
1888 moloc_coeff=moloc_coeff)
1891 vectors => moloc_coeff(1)
1896 ncol_global=n_centers, nrow_global=n_centers)
1898 IF (cell%orthorhombic)
THEN
1903 ALLOCATE (zij_fm_set(2, dim_op))
1911 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1913 DO ispin = 1, nspins
1915 vectors => moloc_coeff(ispin)
1920 CALL parallel_gemm(
"T",
"N", n_centers, n_centers, nao, 1.0_dp, vectors, opvec, 0.0_dp, &
1927 cell=cell, weights=weights, ispin=ispin, &
1928 print_loc_section=print_loc_section, only_initial_out=.true.)
1937 qs_loc_env%do_localize = xas_tdp_control%do_loc
1939 END SUBROUTINE find_mo_centers
1948 SUBROUTINE print_checks(xas_tdp_env, xas_tdp_control, qs_env)
1954 CHARACTER(LEN=default_string_length) :: kind_name
1955 INTEGER :: current_state_index, iat, iatom, ikind, &
1956 istate, output_unit, tmp_index
1957 INTEGER,
DIMENSION(:),
POINTER :: atoms_of_kind
1961 NULLIFY (atomic_kind_set, atoms_of_kind, current_state)
1965 IF (output_unit > 0)
THEN
1966 WRITE (output_unit,
"(/,T3,A,/,T3,A,/,T3,A)") &
1967 "# Check the donor states for their quality. They need to have a well defined type ", &
1968 " (1s, 2s, etc) which is indicated by the overlap. They also need to be localized, ", &
1969 " for which the Mulliken population analysis is one indicator (must be close to 1.0)"
1973 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
1974 current_state_index = 1
1977 DO ikind = 1,
SIZE(atomic_kind_set)
1979 CALL get_atomic_kind(atomic_kind=atomic_kind_set(ikind), name=kind_name, &
1980 atom_list=atoms_of_kind)
1982 IF (.NOT. any(xas_tdp_env%ex_kind_indices == ikind)) cycle
1985 DO iat = 1,
SIZE(atoms_of_kind)
1986 iatom = atoms_of_kind(iat)
1988 IF (.NOT. any(xas_tdp_env%ex_atom_indices == iatom)) cycle
1989 tmp_index =
locate(xas_tdp_env%ex_atom_indices, iatom)
1992 DO istate = 1,
SIZE(xas_tdp_env%state_types, 1)
1994 IF (xas_tdp_env%state_types(istate, tmp_index) ==
xas_not_excited) cycle
1996 current_state => xas_tdp_env%donor_states(current_state_index)
1998 at_symbol=kind_name, kind_index=ikind, &
1999 state_type=xas_tdp_env%state_types(istate, tmp_index))
2001 IF (output_unit > 0)
THEN
2002 WRITE (output_unit,
"(/,T4,A,A2,A,I4,A,A,A)") &
2003 "-Donor state of type ", xas_tdp_env%state_type_char(current_state%state_type), &
2004 " for atom", current_state%at_index,
" of kind ", trim(current_state%at_symbol),
":"
2008 CALL assign_mos_to_donor_state(current_state, xas_tdp_env, xas_tdp_control, qs_env)
2009 CALL perform_mulliken_on_donor_state(current_state, qs_env)
2011 current_state_index = current_state_index + 1
2012 NULLIFY (current_state)
2018 IF (output_unit > 0)
THEN
2019 WRITE (output_unit,
"(/,T5,A)") &
2020 "Use LOCALIZE and/or increase N_SEARCH for better results, if so required."
2023 END SUBROUTINE print_checks
2033 SUBROUTINE compute_lenrep_multipole(iatom, xas_tdp_env, xas_tdp_control, qs_env)
2035 INTEGER,
INTENT(IN) :: iatom
2041 REAL(
dp),
DIMENSION(3) :: rc
2045 NULLIFY (work, particle_set)
2047 CALL get_qs_env(qs_env, particle_set=particle_set)
2048 rc = particle_set(iatom)%r
2051 IF (xas_tdp_control%dipole_form ==
xas_dip_len)
THEN
2053 CALL dbcsr_set(xas_tdp_env%dipmat(i)%matrix, 0.0_dp)
2054 work(i)%matrix => xas_tdp_env%dipmat(i)%matrix
2058 IF (xas_tdp_control%do_quad)
THEN
2060 CALL dbcsr_set(xas_tdp_env%quadmat(i)%matrix, 0.0_dp)
2061 work(3 + i)%matrix => xas_tdp_env%quadmat(i)%matrix
2064 IF (xas_tdp_control%dipole_form ==
xas_dip_vel) order = -2
2068 CALL rrc_xyz_ao(work, qs_env, rc, order=order, minimum_image=.true.)
2071 END SUBROUTINE compute_lenrep_multipole
2085 SUBROUTINE compute_dipole_fosc(donor_state, xas_tdp_control, xas_tdp_env)
2091 CHARACTER(len=*),
PARAMETER :: routinen =
'compute_dipole_fosc'
2093 INTEGER :: handle, iosc, j, nao, ndo_mo, ndo_so, &
2095 LOGICAL :: do_sc, do_sg
2096 REAL(
dp) :: alpha_xyz, beta_xyz, osc_xyz, pref
2097 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: alpha_contr, beta_contr, tot_contr
2098 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: dip_block
2099 REAL(
dp),
DIMENSION(:),
POINTER :: lr_evals
2100 REAL(
dp),
DIMENSION(:, :),
POINTER :: alpha_osc, beta_osc, osc_str
2108 NULLIFY (dipmat, col_struct, mat_struct, para_env, blacs_env, lr_coeffs)
2109 NULLIFY (lr_evals, osc_str, alpha_osc, beta_osc)
2111 CALL timeset(routinen, handle)
2114 do_sc = xas_tdp_control%do_spin_cons
2115 do_sg = xas_tdp_control%do_singlet
2118 lr_evals => donor_state%sc_evals
2119 lr_coeffs => donor_state%sc_coeffs
2120 ELSE IF (do_sg)
THEN
2122 lr_evals => donor_state%sg_evals
2123 lr_coeffs => donor_state%sg_coeffs
2125 cpabort(
"Dipole oscilaltor strength only for singlets and spin-conserving excitations.")
2127 ndo_mo = donor_state%ndo_mo
2128 ndo_so = ndo_mo*nspins
2129 ngs = ndo_so;
IF (xas_tdp_control%do_roks) ngs = ndo_mo
2130 nosc =
SIZE(lr_evals)
2131 ALLOCATE (donor_state%osc_str(nosc, 4), donor_state%alpha_osc(nosc, 4), donor_state%beta_osc(nosc, 4))
2132 osc_str => donor_state%osc_str
2133 alpha_osc => donor_state%alpha_osc
2134 beta_osc => donor_state%beta_osc
2138 dipmat => xas_tdp_env%dipmat
2141 CALL cp_fm_get_info(donor_state%gs_coeffs, matrix_struct=col_struct, para_env=para_env, &
2142 context=blacs_env, nrow_global=nao)
2144 nrow_global=ndo_so*nosc, ncol_global=ngs)
2148 ALLOCATE (tot_contr(ndo_mo), dip_block(ndo_so, ngs), alpha_contr(ndo_mo), beta_contr(ndo_mo))
2149 pref = 2.0_dp;
IF (do_sc) pref = 1.0_dp
2157 CALL parallel_gemm(
'T',
'N', ndo_so*nosc, ngs, nao, 1.0_dp, lr_coeffs, col_work, 0.0_dp, mat_work)
2163 CALL cp_fm_get_submatrix(fm=mat_work, target_m=dip_block, start_row=(iosc - 1)*ndo_so + 1, &
2164 start_col=1, n_rows=ndo_so, n_cols=ngs)
2167 ELSE IF (do_sc .AND. xas_tdp_control%do_uks)
THEN
2168 alpha_contr(:) =
get_diag(dip_block(1:ndo_mo, 1:ndo_mo))
2169 beta_contr(:) =
get_diag(dip_block(ndo_mo + 1:ndo_so, ndo_mo + 1:ndo_so))
2170 tot_contr(:) = alpha_contr(:) + beta_contr(:)
2173 alpha_contr(:) =
get_diag(dip_block(1:ndo_mo, :))
2174 beta_contr(:) =
get_diag(dip_block(ndo_mo + 1:ndo_so, :))
2175 tot_contr(:) = alpha_contr(:) + beta_contr(:)
2178 osc_xyz = sum(tot_contr)**2
2179 alpha_xyz = sum(alpha_contr)**2
2180 beta_xyz = sum(beta_contr)**2
2182 alpha_osc(iosc, 4) = alpha_osc(iosc, 4) + alpha_xyz
2183 alpha_osc(iosc, j) = alpha_xyz
2185 beta_osc(iosc, 4) = beta_osc(iosc, 4) + beta_xyz
2186 beta_osc(iosc, j) = beta_xyz
2188 osc_str(iosc, 4) = osc_str(iosc, 4) + osc_xyz
2189 osc_str(iosc, j) = osc_xyz
2196 IF (xas_tdp_control%dipole_form ==
xas_dip_len)
THEN
2197 osc_str(:, j) = pref*2.0_dp/3.0_dp*lr_evals(:)*osc_str(:, j)
2198 alpha_osc(:, j) = pref*2.0_dp/3.0_dp*lr_evals(:)*alpha_osc(:, j)
2199 beta_osc(:, j) = pref*2.0_dp/3.0_dp*lr_evals(:)*beta_osc(:, j)
2201 osc_str(:, j) = pref*2.0_dp/3.0_dp/lr_evals(:)*osc_str(:, j)
2202 alpha_osc(:, j) = pref*2.0_dp/3.0_dp/lr_evals(:)*alpha_osc(:, j)
2203 beta_osc(:, j) = pref*2.0_dp/3.0_dp/lr_evals(:)*beta_osc(:, j)
2212 CALL timestop(handle)
2214 END SUBROUTINE compute_dipole_fosc
2224 SUBROUTINE compute_quadrupole_fosc(donor_state, xas_tdp_control, xas_tdp_env)
2230 CHARACTER(len=*),
PARAMETER :: routinen =
'compute_quadrupole_fosc'
2232 INTEGER :: handle, iosc, j, nao, ndo_mo, ndo_so, &
2234 LOGICAL :: do_sc, do_sg
2236 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: tot_contr, trace
2237 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: quad_block
2238 REAL(
dp),
DIMENSION(:),
POINTER :: lr_evals, osc_str
2246 NULLIFY (lr_evals, osc_str, lr_coeffs, col_struct, mat_struct, para_env)
2249 CALL timeset(routinen, handle)
2252 do_sc = xas_tdp_control%do_spin_cons
2253 do_sg = xas_tdp_control%do_singlet
2256 lr_evals => donor_state%sc_evals
2257 lr_coeffs => donor_state%sc_coeffs
2258 ELSE IF (do_sg)
THEN
2260 lr_evals => donor_state%sg_evals
2261 lr_coeffs => donor_state%sg_coeffs
2263 cpabort(
"Quadrupole oscillator strengths only for singlet and spin-conserving excitations")
2265 ndo_mo = donor_state%ndo_mo
2266 ndo_so = ndo_mo*nspins
2267 ngs = ndo_so;
IF (xas_tdp_control%do_roks) ngs = ndo_mo
2268 nosc =
SIZE(lr_evals)
2269 ALLOCATE (donor_state%quad_osc_str(nosc))
2270 osc_str => donor_state%quad_osc_str
2272 quadmat => xas_tdp_env%quadmat
2275 CALL cp_fm_get_info(donor_state%gs_coeffs, matrix_struct=col_struct, para_env=para_env, &
2276 context=blacs_env, nrow_global=nao)
2278 nrow_global=ndo_so*nosc, ncol_global=ngs)
2282 ALLOCATE (quad_block(ndo_so, ngs), tot_contr(ndo_mo))
2283 pref = 2.0_dp;
IF (do_sc) pref = 1.0_dp
2284 ALLOCATE (trace(nosc))
2293 CALL parallel_gemm(
'T',
'N', ndo_so*nosc, ngs, nao, 1.0_dp, lr_coeffs, col_work, 0.0_dp, mat_work)
2299 CALL cp_fm_get_submatrix(fm=mat_work, target_m=quad_block, start_row=(iosc - 1)*ndo_so + 1, &
2300 start_col=1, n_rows=ndo_so, n_cols=ngs)
2303 tot_contr(:) =
get_diag(quad_block)
2304 ELSE IF (do_sc .AND. xas_tdp_control%do_uks)
THEN
2305 tot_contr(:) =
get_diag(quad_block(1:ndo_mo, 1:ndo_mo))
2306 tot_contr(:) = tot_contr(:) +
get_diag(quad_block(ndo_mo + 1:ndo_so, ndo_mo + 1:ndo_so))
2309 tot_contr(:) =
get_diag(quad_block(1:ndo_mo, :))
2310 tot_contr(:) = tot_contr(:) +
get_diag(quad_block(ndo_mo + 1:ndo_so, :))
2314 IF (j == 1 .OR. j == 4 .OR. j == 6)
THEN
2315 osc_str(iosc) = osc_str(iosc) + sum(tot_contr)**2
2316 trace(iosc) = trace(iosc) + sum(tot_contr)
2320 osc_str(iosc) = osc_str(iosc) + 2.0_dp*sum(tot_contr)**2
2327 osc_str(:) = pref*1._dp/20._dp*
a_fine**2*lr_evals(:)**3*(osc_str(:) - 1._dp/3._dp*trace(:)**2)
2334 CALL timestop(handle)
2336 END SUBROUTINE compute_quadrupole_fosc
2345 SUBROUTINE write_mos_to_ex_atoms_association(xas_tdp_env, xas_tdp_control, qs_env)
2351 CHARACTER(LEN=default_string_length) :: kind_name
2352 INTEGER :: at_index, imo, ispin, nmo, nspins, &
2353 output_unit, tmp_index
2354 INTEGER,
DIMENSION(3) :: perd_init
2355 INTEGER,
DIMENSION(:),
POINTER :: ex_atom_indices
2356 INTEGER,
DIMENSION(:, :, :),
POINTER :: mos_of_ex_atoms
2357 REAL(
dp) :: dist, mo_spread
2358 REAL(
dp),
DIMENSION(3) :: at_pos, r_ac, wfn_center
2362 NULLIFY (cell, particle_set, mos_of_ex_atoms, ex_atom_indices)
2366 IF (output_unit > 0)
THEN
2367 WRITE (unit=output_unit, fmt=
"(/,T3,A,/,T3,A,/,T3,A)") &
2368 " Associated Associated Distance to MO spread (Ang^2)", &
2369 "Spin MO index atom index atom kind MO center (Ang) -w_i ln(|z_ij|^2)", &
2370 "---------------------------------------------------------------------------------"
2374 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
2375 mos_of_ex_atoms => xas_tdp_env%mos_of_ex_atoms
2376 ex_atom_indices => xas_tdp_env%ex_atom_indices
2377 nmo = xas_tdp_control%n_search
2378 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, cell=cell)
2381 perd_init = cell%perd
2386 DO ispin = 1, nspins
2389 IF (any(mos_of_ex_atoms(imo, :, ispin) == 1))
THEN
2390 tmp_index = maxloc(mos_of_ex_atoms(imo, :, ispin), 1)
2391 at_index = ex_atom_indices(tmp_index)
2392 kind_name = particle_set(at_index)%atomic_kind%name
2394 at_pos = particle_set(at_index)%r
2395 wfn_center = xas_tdp_env%qs_loc_env%localized_wfn_control%centers_set(ispin)%array(1:3, imo)
2396 r_ac =
pbc(at_pos, wfn_center, cell)
2401 mo_spread = xas_tdp_env%qs_loc_env%localized_wfn_control%centers_set(ispin)%array(4, imo)
2404 IF (output_unit > 0)
THEN
2405 WRITE (unit=output_unit, fmt=
"(T3,I4,I10,I14,A14,ES19.3,ES20.3)") &
2406 ispin, imo, at_index, trim(kind_name), dist, mo_spread
2413 IF (output_unit > 0)
THEN
2414 WRITE (unit=output_unit, fmt=
"(T3,A,/)") &
2415 "---------------------------------------------------------------------------------"
2419 cell%perd = perd_init
2421 END SUBROUTINE write_mos_to_ex_atoms_association
2432 SUBROUTINE perform_mulliken_on_donor_state(donor_state, qs_env)
2436 INTEGER :: at_index, i, ispin, nao, natom, ndo_mo, &
2437 ndo_so, nsgf, nspins, output_unit
2438 INTEGER,
DIMENSION(:),
POINTER :: first_sgf, last_sgf
2439 INTEGER,
DIMENSION(:, :),
POINTER :: mo_indices
2440 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: mul_pop, pop_mat
2441 REAL(
dp),
DIMENSION(:, :),
POINTER :: work_array
2449 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2451 NULLIFY (mo_indices, qs_kind_set, particle_set, first_sgf, work_array)
2452 NULLIFY (matrix_s, para_env, blacs_env, col_vect_struct, last_sgf)
2455 at_index = donor_state%at_index
2456 mo_indices => donor_state%mo_indices
2457 ndo_mo = donor_state%ndo_mo
2458 gs_coeffs => donor_state%gs_coeffs
2460 nspins = 1;
IF (
SIZE(mo_indices, 2) == 2) nspins = 2
2461 ndo_so = ndo_mo*nspins
2462 ALLOCATE (mul_pop(ndo_mo, nspins))
2465 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, qs_kind_set=qs_kind_set, &
2466 para_env=para_env, blacs_env=blacs_env, matrix_s=matrix_s)
2467 CALL cp_fm_get_info(gs_coeffs, nrow_global=nao, matrix_struct=col_vect_struct)
2469 natom =
SIZE(particle_set, 1)
2470 ALLOCATE (first_sgf(natom))
2471 ALLOCATE (last_sgf(natom))
2473 CALL get_particle_set(particle_set, qs_kind_set, first_sgf=first_sgf, last_sgf=last_sgf)
2474 nsgf = last_sgf(at_index) - first_sgf(at_index) + 1
2482 ALLOCATE (work_array(nsgf, ndo_so))
2483 ALLOCATE (pop_mat(ndo_so, ndo_so))
2485 CALL cp_fm_get_submatrix(fm=work_vect, target_m=work_array, start_row=first_sgf(at_index), &
2486 start_col=1, n_rows=nsgf, n_cols=ndo_so, transpose=.false.)
2488 CALL dgemm(
'T',
'N', ndo_so, ndo_so, nsgf, 1.0_dp, donor_state%contract_coeffs, nsgf, &
2489 work_array, nsgf, 0.0_dp, pop_mat, ndo_so)
2492 DO ispin = 1, nspins
2494 mul_pop(i, ispin) = pop_mat((ispin - 1)*ndo_mo + i, (ispin - 1)*ndo_mo + i)
2499 IF (output_unit > 0)
THEN
2500 WRITE (unit=output_unit, fmt=
"(T5,A,/,T5,A)") &
2501 "Mulliken population analysis retricted to the associated MO(s) yields: ", &
2502 " Spin MO index charge"
2503 DO ispin = 1, nspins
2505 WRITE (unit=output_unit, fmt=
"(T51,I4,I10,F11.3)") &
2506 ispin, mo_indices(i, ispin), mul_pop(i, ispin)
2512 DEALLOCATE (first_sgf, last_sgf, work_array)
2515 END SUBROUTINE perform_mulliken_on_donor_state
2525 SUBROUTINE xas_tdp_post(ex_type, donor_state, xas_tdp_env, xas_tdp_section, qs_env)
2527 INTEGER,
INTENT(IN) :: ex_type
2533 CHARACTER(len=*),
PARAMETER :: routinen =
'xas_tdp_post'
2535 CHARACTER(len=default_string_length) :: domo, domon, excite, pos, xas_mittle
2536 INTEGER :: ex_state_idx, handle, ic, ido_mo, imo, irep, ispin, n_dependent, n_rep, nao, &
2537 ncubes, ndo_mo, ndo_so, nlumo, nmo, nspins, output_unit
2538 INTEGER,
DIMENSION(:),
POINTER :: bounds,
list, state_list
2539 LOGICAL :: append_cube, do_cubes, do_pdos, &
2541 REAL(
dp),
DIMENSION(:),
POINTER :: lr_evals
2542 REAL(
dp),
DIMENSION(:, :),
POINTER :: centers
2554 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2557 NULLIFY (atomic_kind_set, particle_set, qs_kind_set, mo_set, lr_evals, lr_coeffs)
2558 NULLIFY (mo_struct, para_env, blacs_env, fm_struct, matrix_s, print_key, logger)
2559 NULLIFY (bounds, state_list,
list, mos)
2563 do_pdos = .false.; do_cubes = .false.; do_wfn_restart = .false.
2566 "PRINT%PDOS"),
cp_p_file)) do_pdos = .true.
2569 "PRINT%CUBES"),
cp_p_file)) do_cubes = .true.
2572 "PRINT%RESTART_WFN"),
cp_p_file)) do_wfn_restart = .true.
2574 IF (.NOT. (do_pdos .OR. do_cubes .OR. do_wfn_restart))
RETURN
2576 CALL timeset(routinen, handle)
2579 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, particle_set=particle_set, &
2580 qs_kind_set=qs_kind_set, para_env=para_env, blacs_env=blacs_env, &
2581 matrix_s=matrix_s, mos=mos)
2583 SELECT CASE (ex_type)
2585 lr_evals => donor_state%sc_evals
2586 lr_coeffs => donor_state%sc_coeffs
2590 lr_evals => donor_state%sf_evals
2591 lr_coeffs => donor_state%sf_coeffs
2595 lr_evals => donor_state%sg_evals
2596 lr_coeffs => donor_state%sg_coeffs
2600 lr_evals => donor_state%tp_evals
2601 lr_coeffs => donor_state%tp_coeffs
2606 SELECT CASE (donor_state%state_type)
2615 ndo_mo = donor_state%ndo_mo
2616 ndo_so = ndo_mo*nspins
2617 nmo =
SIZE(lr_evals)
2621 nrow_global=nao, ncol_global=nmo)
2625 IF (do_wfn_restart)
THEN
2628 IF (.NOT. (nspins == 1 .AND. donor_state%state_type ==
xas_1s_type))
THEN
2629 cpabort(
"RESTART.wfn file only available for RKS K-edge XAS spectroscopy")
2632 CALL section_vals_val_get(xas_tdp_section,
"PRINT%RESTART_WFN%EXCITED_STATE_INDEX", n_rep_val=n_rep)
2636 i_rep_val=irep, i_val=ex_state_idx)
2637 cpassert(ex_state_idx <=
SIZE(lr_evals))
2642 IF (
SIZE(mos) == 1) &
2643 restart_mos(ispin)%occupation_numbers = mos(1)%occupation_numbers/2
2646 CALL cp_fm_to_fm_submat(msource=lr_coeffs, mtarget=restart_mos(1)%mo_coeff, nrow=nao, &
2647 ncol=1, s_firstrow=1, s_firstcol=ex_state_idx, t_firstrow=1, &
2648 t_firstcol=donor_state%mo_indices(1, 1))
2650 xas_mittle =
'xasat'//trim(adjustl(
cp_to_string(donor_state%at_index)))//
'_'//trim(domo)// &
2651 '_'//trim(excite)//
'_idx'//trim(adjustl(
cp_to_string(ex_state_idx)))
2653 extension=
".wfn", file_status=
"REPLACE", &
2654 file_action=
"WRITE", file_form=
"UNFORMATTED", &
2655 middle_name=xas_mittle)
2658 qs_kind_set=qs_kind_set, ires=output_unit)
2673 IF (.NOT.
ASSOCIATED(xas_tdp_env%matrix_shalf) .AND. do_pdos)
THEN
2675 nrow_global=nao, ncol_global=nao)
2676 ALLOCATE (xas_tdp_env%matrix_shalf)
2681 CALL cp_fm_power(xas_tdp_env%matrix_shalf, work_fm, 0.5_dp, epsilon(0.0_dp), n_dependent)
2689 IF (output_unit > 0)
THEN
2690 WRITE (unit=output_unit, fmt=
"(/,T5,A,/,T5,A,/,T5,A)") &
2691 "Computing the PDOS of linear-response orbitals for spectral features analysis", &
2692 "Note: using standard PDOS routines => ignore mentions of KS states and MO ", &
2693 " occupation numbers. Eigenvalues in *.pdos files are excitations energies."
2698 IF (nlumo /= 0)
THEN
2699 cpwarn(
"NLUMO is irrelevant for XAS_TDP PDOS. It was overwritten to 0.")
2710 ncubes = bounds(2) - bounds(1) + 1
2711 IF (ncubes > 0)
THEN
2712 ALLOCATE (state_list(ncubes))
2714 state_list(ic) = bounds(1) + ic - 1
2718 IF (.NOT.
ASSOCIATED(state_list))
THEN
2725 IF (
ASSOCIATED(
list))
THEN
2727 DO ic = 1,
SIZE(
list)
2728 state_list(ncubes + ic) =
list(ic)
2730 ncubes = ncubes +
SIZE(
list)
2735 IF (.NOT.
ASSOCIATED(state_list))
THEN
2737 ALLOCATE (state_list(1))
2743 IF (append_cube) pos =
"APPEND"
2745 ALLOCATE (centers(6, ncubes))
2751 DO ido_mo = 1, ndo_mo
2752 DO ispin = 1, nspins
2756 CALL allocate_mo_set(mo_set, nao=nao, nmo=nmo, nelectron=nmo, n_el_f=real(nmo,
dp), &
2757 maxocc=1.0_dp, flexible_electron_count=0.0_dp)
2758 CALL init_mo_set(mo_set, fm_ref=mo_coeff, name=
"PDOS XAS_TDP MOs")
2759 mo_set%eigenvalues(:) = lr_evals(:)
2762 IF (nspins == 1 .AND. ndo_mo == 1)
THEN
2767 nrow=nao, ncol=1, s_firstrow=1, &
2768 s_firstcol=(imo - 1)*ndo_so + (ispin - 1)*ndo_mo + ido_mo, &
2769 t_firstrow=1, t_firstcol=imo)
2776 xas_mittle =
'xasat'//trim(adjustl(
cp_to_string(donor_state%at_index)))//
'_'// &
2777 trim(domon)//
'_'//trim(excite)
2781 qs_env, xas_tdp_section, ispin, xas_mittle, &
2782 external_matrix_shalf=xas_tdp_env%matrix_shalf)
2786 CALL qs_print_cubes(qs_env, mo_set%mo_coeff, ncubes, state_list, centers, &
2787 print_key=print_key, root=xas_mittle, ispin=ispin, &
2801 IF (do_cubes)
DEALLOCATE (centers, state_list)
2803 CALL timestop(handle)
2805 END SUBROUTINE xas_tdp_post
2815 SUBROUTINE make_lumo_guess(xas_tdp_env, xas_tdp_control, qs_env)
2817 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2818 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2819 TYPE(qs_environment_type),
POINTER :: qs_env
2821 CHARACTER(len=*),
PARAMETER :: routinen =
'make_lumo_guess'
2823 INTEGER :: handle, ispin, nao, nelec_spin(2), &
2824 nlumo(2), nocc(2), nspins
2826 REAL(dp),
ALLOCATABLE,
DIMENSION(:) :: evals
2827 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
2828 TYPE(cp_fm_struct_type),
POINTER :: fm_struct, lumo_struct
2829 TYPE(cp_fm_type) :: amatrix, bmatrix, evecs, work_fm
2830 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_ks, matrix_s
2831 TYPE(mp_para_env_type),
POINTER :: para_env
2833 NULLIFY (matrix_ks, matrix_s, para_env, blacs_env)
2834 NULLIFY (lumo_struct, fm_struct)
2836 CALL timeset(routinen, handle)
2838 do_os = xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks
2839 nspins = 1;
IF (do_os) nspins = 2
2840 ALLOCATE (xas_tdp_env%lumo_evecs(nspins))
2841 ALLOCATE (xas_tdp_env%lumo_evals(nspins))
2842 CALL get_qs_env(qs_env, matrix_ks=matrix_ks, matrix_s=matrix_s, nelectron_spin=nelec_spin, &
2843 para_env=para_env, blacs_env=blacs_env)
2844 CALL dbcsr_get_info(matrix_s(1)%matrix, nfullrows_total=nao)
2847 nlumo = nao - nelec_spin
2850 nlumo = nao - nelec_spin(1)/2
2851 nocc = nelec_spin(1)/2
2854 ALLOCATE (xas_tdp_env%ot_prec(nspins))
2856 DO ispin = 1, nspins
2859 CALL cp_fm_struct_create(fm_struct, para_env=para_env, context=blacs_env, &
2860 nrow_global=nao, ncol_global=nao)
2861 CALL cp_fm_create(amatrix, fm_struct)
2862 CALL cp_fm_create(bmatrix, fm_struct)
2863 CALL cp_fm_create(evecs, fm_struct)
2864 CALL cp_fm_create(work_fm, fm_struct)
2865 ALLOCATE (evals(nao))
2866 ALLOCATE (xas_tdp_env%lumo_evals(ispin)%array(nlumo(ispin)))
2868 CALL copy_dbcsr_to_fm(matrix_ks(ispin)%matrix, amatrix)
2869 CALL copy_dbcsr_to_fm(matrix_s(1)%matrix, bmatrix)
2872 CALL cp_fm_geeig(amatrix, bmatrix, evecs, evals, work_fm)
2875 CALL cp_fm_struct_create(lumo_struct, para_env=para_env, context=blacs_env, &
2876 nrow_global=nao, ncol_global=nlumo(ispin))
2877 CALL cp_fm_create(xas_tdp_env%lumo_evecs(ispin), lumo_struct)
2879 CALL cp_fm_to_fm_submat(evecs, xas_tdp_env%lumo_evecs(ispin), nrow=nao, &
2880 ncol=nlumo(ispin), s_firstrow=1, s_firstcol=nocc(ispin) + 1, &
2881 t_firstrow=1, t_firstcol=1)
2883 xas_tdp_env%lumo_evals(ispin)%array(1:nlumo(ispin)) = evals(nocc(ispin) + 1:nao)
2885 CALL build_ot_spin_prec(evecs, evals, ispin, xas_tdp_env, xas_tdp_control, qs_env)
2888 CALL cp_fm_release(amatrix)
2889 CALL cp_fm_release(bmatrix)
2890 CALL cp_fm_release(evecs)
2891 CALL cp_fm_release(work_fm)
2892 CALL cp_fm_struct_release(fm_struct)
2893 CALL cp_fm_struct_release(lumo_struct)
2897 CALL timestop(handle)
2899 END SUBROUTINE make_lumo_guess
2912 SUBROUTINE build_ot_spin_prec(evecs, evals, ispin, xas_tdp_env, xas_tdp_control, qs_env)
2914 TYPE(cp_fm_type),
INTENT(IN) :: evecs
2915 REAL(dp),
DIMENSION(:) :: evals
2917 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2918 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2919 TYPE(qs_environment_type),
POINTER :: qs_env
2921 CHARACTER(len=*),
PARAMETER :: routinen =
'build_ot_spin_prec'
2923 INTEGER :: handle, nao, nelec_spin(2), nguess, &
2927 REAL(dp),
ALLOCATABLE,
DIMENSION(:) :: scaling
2928 TYPE(cp_fm_struct_type),
POINTER :: fm_struct
2929 TYPE(cp_fm_type) :: fm_prec, work_fm
2930 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_s
2931 TYPE(mp_para_env_type),
POINTER :: para_env
2933 NULLIFY (fm_struct, para_env, matrix_s)
2935 CALL timeset(routinen, handle)
2937 do_os = xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks
2938 CALL get_qs_env(qs_env, para_env=para_env, nelectron_spin=nelec_spin, matrix_s=matrix_s)
2939 CALL cp_fm_get_info(evecs, nrow_global=nao, matrix_struct=fm_struct)
2940 CALL cp_fm_create(fm_prec, fm_struct)
2941 ALLOCATE (scaling(nao))
2942 nocc = nelec_spin(1)/2
2945 nocc = nelec_spin(ispin)
2951 IF (xas_tdp_control%n_excited > 0 .AND. xas_tdp_control%n_excited < nguess)
THEN
2952 nguess = xas_tdp_control%n_excited/nspins
2953 ELSE IF (xas_tdp_control%e_range > 0.0_dp)
THEN
2954 nguess = count(evals(nocc + 1:nao) - evals(nocc + 1) <= xas_tdp_control%e_range)
2958 scaling(nocc + 1:nocc + nguess) = 100.0_dp
2960 shift = evals(nocc + 1) - 0.01_dp
2961 scaling(nocc + nguess:nao) = 1.0_dp/(evals(nocc + nguess:nao) - shift)
2963 scaling(1:nocc) = 1.0_dp
2966 CALL cp_fm_create(work_fm, fm_struct)
2968 CALL cp_fm_copy_general(evecs, work_fm, para_env)
2969 CALL cp_fm_column_scale(work_fm, scaling)
2971 CALL parallel_gemm(
'N',
'T', nao, nao, nao, 1.0_dp, work_fm, evecs, 0.0_dp, fm_prec)
2974 ALLOCATE (xas_tdp_env%ot_prec(ispin)%matrix)
2975 CALL dbcsr_create(xas_tdp_env%ot_prec(ispin)%matrix, template=matrix_s(1)%matrix, name=
"OT_PREC")
2976 CALL copy_fm_to_dbcsr(fm_prec, xas_tdp_env%ot_prec(ispin)%matrix)
2977 CALL dbcsr_filter(xas_tdp_env%ot_prec(ispin)%matrix, xas_tdp_control%eps_filter)
2979 CALL cp_fm_release(work_fm)
2980 CALL cp_fm_release(fm_prec)
2982 CALL timestop(handle)
2984 END SUBROUTINE build_ot_spin_prec
2993 SUBROUTINE print_xps(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
2995 TYPE(donor_state_type),
POINTER :: donor_state
2996 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2997 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2998 TYPE(qs_environment_type),
POINTER :: qs_env
3000 INTEGER :: ido_mo, ispin, nspins, output_unit
3001 REAL(dp),
ALLOCATABLE,
DIMENSION(:, :) :: ips, soc_shifts
3003 output_unit = cp_logger_get_default_io_unit()
3005 nspins = 1;
IF (xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks) nspins = 2
3007 ALLOCATE (ips(
SIZE(donor_state%gw2x_evals, 1),
SIZE(donor_state%gw2x_evals, 2)))
3008 ips(:, :) = donor_state%gw2x_evals(:, :)
3011 IF (.NOT. xas_tdp_control%is_periodic)
THEN
3014 IF (donor_state%ndo_mo > 1)
THEN
3015 CALL get_soc_splitting(soc_shifts, donor_state, xas_tdp_env, xas_tdp_control, qs_env)
3016 ips(:, :) = ips(:, :) + soc_shifts
3018 IF (output_unit > 0)
THEN
3019 WRITE (output_unit, fmt=
"(/,T5,A,F23.6)") &
3020 "Ionization potentials for XPS (GW2X + SOC): ", -ips(1, 1)*evolt
3022 DO ispin = 1, nspins
3023 DO ido_mo = 1, donor_state%ndo_mo
3025 IF (ispin == 1 .AND. ido_mo == 1) cycle
3027 WRITE (output_unit, fmt=
"(T5,A,F23.6)") &
3028 " ", -ips(ido_mo, ispin)*evolt
3037 IF (output_unit > 0)
THEN
3038 WRITE (output_unit, fmt=
"(/,T5,A,F29.6)") &
3039 "Ionization potentials for XPS (GW2X): ", -ips(1, 1)*evolt
3041 IF (nspins == 2)
THEN
3042 WRITE (output_unit, fmt=
"(T5,A,F29.6)") &
3043 " ", -ips(1, 2)*evolt
3050 END SUBROUTINE print_xps
3059 SUBROUTINE print_xas_tdp_to_file(donor_state, xas_tdp_env, xas_tdp_control, xas_tdp_section)
3061 TYPE(donor_state_type),
POINTER :: donor_state
3062 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
3063 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
3064 TYPE(section_vals_type),
POINTER :: xas_tdp_section
3066 INTEGER :: i, output_unit, xas_tdp_unit
3067 TYPE(cp_logger_type),
POINTER :: logger
3070 logger => cp_get_default_logger()
3072 xas_tdp_unit = cp_print_key_unit_nr(logger, xas_tdp_section,
"PRINT%SPECTRUM", &
3073 extension=
".spectrum", file_position=
"APPEND", &
3074 file_action=
"WRITE", file_form=
"FORMATTED")
3076 output_unit = cp_logger_get_default_io_unit()
3078 IF (output_unit > 0)
THEN
3079 WRITE (output_unit, fmt=
"(/,T5,A,/)") &
3080 "Calculations done: "
3083 IF (xas_tdp_control%do_spin_cons)
THEN
3084 IF (xas_tdp_unit > 0)
THEN
3087 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3088 "==================================================================================", &
3089 "XAS TDP open-shell spin-conserving (no SOC) excitations for DONOR STATE: ", &
3090 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3091 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3092 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3093 "=================================================================================="
3097 IF (xas_tdp_control%do_quad)
THEN
3098 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3099 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3100 DO i = 1,
SIZE(donor_state%sc_evals)
3101 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3102 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4), &
3103 donor_state%quad_osc_str(i)
3105 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3106 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3107 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3108 DO i = 1,
SIZE(donor_state%sc_evals)
3109 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3110 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4), &
3111 donor_state%osc_str(i, 1), donor_state%osc_str(i, 2), donor_state%osc_str(i, 3)
3113 ELSE IF (xas_tdp_control%spin_dip)
THEN
3114 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3115 " Index Excitation energy (eV) fosc dipole (a.u.) alpha-comp beta-comp"
3116 DO i = 1,
SIZE(donor_state%sc_evals)
3117 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6)") &
3118 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4), &
3119 donor_state%alpha_osc(i, 4), donor_state%beta_osc(i, 4)
3122 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3123 " Index Excitation energy (eV) fosc dipole (a.u.)"
3124 DO i = 1,
SIZE(donor_state%sc_evals)
3125 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3126 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4)
3130 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3133 IF (output_unit > 0)
THEN
3134 WRITE (output_unit, fmt=
"(T5,A,F17.6)") &
3135 "First spin-conserving XAS excitation energy (eV): ", donor_state%sc_evals(1)*evolt
3140 IF (xas_tdp_control%do_spin_flip)
THEN
3141 IF (xas_tdp_unit > 0)
THEN
3144 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3145 "==================================================================================", &
3146 "XAS TDP open-shell spin-flip (no SOC) excitations for DONOR STATE: ", &
3147 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3148 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3149 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3150 "=================================================================================="
3154 IF (xas_tdp_control%do_quad)
THEN
3155 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3156 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3157 DO i = 1,
SIZE(donor_state%sf_evals)
3158 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3159 i, donor_state%sf_evals(i)*evolt, 0.0_dp, 0.0_dp
3161 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3162 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3163 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3164 DO i = 1,
SIZE(donor_state%sf_evals)
3165 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3166 i, donor_state%sf_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp
3168 ELSE IF (xas_tdp_control%spin_dip)
THEN
3169 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3170 " Index Excitation energy (eV) fosc dipole (a.u.) alpha-comp beta-comp"
3171 DO i = 1,
SIZE(donor_state%sf_evals)
3172 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6)") &
3173 i, donor_state%sf_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp
3176 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3177 " Index Excitation energy (eV) fosc dipole (a.u.)"
3178 DO i = 1,
SIZE(donor_state%sf_evals)
3179 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3180 i, donor_state%sf_evals(i)*evolt, 0.0_dp
3184 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3187 IF (output_unit > 0)
THEN
3188 WRITE (output_unit, fmt=
"(T5,A,F23.6)") &
3189 "First spin-flip XAS excitation energy (eV): ", donor_state%sf_evals(1)*evolt
3193 IF (xas_tdp_control%do_singlet)
THEN
3194 IF (xas_tdp_unit > 0)
THEN
3197 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3198 "==================================================================================", &
3199 "XAS TDP singlet excitations (no SOC) for DONOR STATE: ", &
3200 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3201 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3202 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3203 "=================================================================================="
3207 IF (xas_tdp_control%do_quad)
THEN
3208 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3209 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3210 DO i = 1,
SIZE(donor_state%sg_evals)
3211 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3212 i, donor_state%sg_evals(i)*evolt, donor_state%osc_str(i, 4), &
3213 donor_state%quad_osc_str(i)
3215 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3216 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3217 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3218 DO i = 1,
SIZE(donor_state%sg_evals)
3219 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3220 i, donor_state%sg_evals(i)*evolt, donor_state%osc_str(i, 4), &
3221 donor_state%osc_str(i, 1), donor_state%osc_str(i, 2), donor_state%osc_str(i, 3)
3224 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3225 " Index Excitation energy (eV) fosc dipole (a.u.)"
3226 DO i = 1,
SIZE(donor_state%sg_evals)
3227 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3228 i, donor_state%sg_evals(i)*evolt, donor_state%osc_str(i, 4)
3232 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3235 IF (output_unit > 0)
THEN
3236 WRITE (output_unit, fmt=
"(T5,A,F25.6)") &
3237 "First singlet XAS excitation energy (eV): ", donor_state%sg_evals(1)*evolt
3241 IF (xas_tdp_control%do_triplet)
THEN
3242 IF (xas_tdp_unit > 0)
THEN
3245 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3246 "==================================================================================", &
3247 "XAS TDP triplet excitations (no SOC) for DONOR STATE: ", &
3248 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3249 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3250 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3251 "=================================================================================="
3255 IF (xas_tdp_control%do_quad)
THEN
3256 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3257 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3258 DO i = 1,
SIZE(donor_state%tp_evals)
3259 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3260 i, donor_state%tp_evals(i)*evolt, 0.0_dp, 0.0_dp
3262 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3263 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3264 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3265 DO i = 1,
SIZE(donor_state%tp_evals)
3266 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3267 i, donor_state%tp_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp
3269 ELSE IF (xas_tdp_control%spin_dip)
THEN
3270 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3271 " Index Excitation energy (eV) fosc dipole (a.u.) alpha-comp beta-comp"
3272 DO i = 1,
SIZE(donor_state%tp_evals)
3273 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6)") &
3274 i, donor_state%tp_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp
3277 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3278 " Index Excitation energy (eV) fosc dipole (a.u.)"
3279 DO i = 1,
SIZE(donor_state%tp_evals)
3280 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3281 i, donor_state%tp_evals(i)*evolt, 0.0_dp
3285 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3288 IF (output_unit > 0)
THEN
3289 WRITE (output_unit, fmt=
"(T5,A,F25.6)") &
3290 "First triplet XAS excitation energy (eV): ", donor_state%tp_evals(1)*evolt
3294 IF (xas_tdp_control%do_soc .AND. donor_state%state_type == xas_2p_type)
THEN
3295 IF (xas_tdp_unit > 0)
THEN
3298 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3299 "==================================================================================", &
3300 "XAS TDP excitations after spin-orbit coupling for DONOR STATE: ", &
3301 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3302 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3303 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3304 "=================================================================================="
3307 IF (xas_tdp_control%do_quad)
THEN
3308 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3309 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3310 DO i = 1,
SIZE(donor_state%soc_evals)
3311 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3312 i, donor_state%soc_evals(i)*evolt, donor_state%soc_osc_str(i, 4), &
3313 donor_state%soc_quad_osc_str(i)
3315 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3316 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3317 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3318 DO i = 1,
SIZE(donor_state%soc_evals)
3319 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3320 i, donor_state%soc_evals(i)*evolt, donor_state%soc_osc_str(i, 4), &
3321 donor_state%soc_osc_str(i, 1), donor_state%soc_osc_str(i, 2), donor_state%soc_osc_str(i, 3)
3324 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3325 " Index Excitation energy (eV) fosc dipole (a.u.)"
3326 DO i = 1,
SIZE(donor_state%soc_evals)
3327 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3328 i, donor_state%soc_evals(i)*evolt, donor_state%soc_osc_str(i, 4)
3332 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3335 IF (output_unit > 0)
THEN
3336 WRITE (output_unit, fmt=
"(T5,A,F29.6)") &
3337 "First SOC XAS excitation energy (eV): ", donor_state%soc_evals(1)*evolt
3341 CALL cp_print_key_finished_output(xas_tdp_unit, logger, xas_tdp_section,
"PRINT%SPECTRUM")
3343 END SUBROUTINE print_xas_tdp_to_file
3353 SUBROUTINE write_donor_state_restart(ex_type, donor_state, xas_tdp_section, qs_env)
3355 INTEGER,
INTENT(IN) :: ex_type
3356 TYPE(donor_state_type),
POINTER :: donor_state
3357 TYPE(section_vals_type),
POINTER :: xas_tdp_section
3358 TYPE(qs_environment_type),
POINTER :: qs_env
3360 CHARACTER(len=*),
PARAMETER :: routinen =
'write_donor_state_restart'
3362 CHARACTER(len=default_path_length) :: filename
3363 CHARACTER(len=default_string_length) :: domo, excite, my_middle
3364 INTEGER :: ex_atom, handle, ispin, nao, ndo_mo, &
3365 nex, nspins, output_unit, rst_unit, &
3367 INTEGER,
DIMENSION(:, :),
POINTER :: mo_indices
3369 REAL(dp),
DIMENSION(:),
POINTER :: lr_evals
3370 TYPE(cp_fm_type),
POINTER :: lr_coeffs
3371 TYPE(cp_logger_type),
POINTER :: logger
3372 TYPE(mo_set_type),
DIMENSION(:),
POINTER :: mos
3373 TYPE(section_vals_type),
POINTER :: print_key
3375 NULLIFY (logger, lr_coeffs, lr_evals, print_key, mos)
3378 logger => cp_get_default_logger()
3380 IF (btest(cp_print_key_should_output(logger%iter_info, xas_tdp_section, &
3381 "PRINT%RESTART", used_print_key=print_key), cp_p_file)) do_print = .true.
3383 IF (.NOT. do_print)
RETURN
3385 CALL timeset(routinen, handle)
3387 output_unit = cp_logger_get_default_io_unit()
3390 SELECT CASE (ex_type)
3391 CASE (tddfpt_spin_cons)
3392 lr_evals => donor_state%sc_evals
3393 lr_coeffs => donor_state%sc_coeffs
3396 CASE (tddfpt_spin_flip)
3397 lr_evals => donor_state%sf_evals
3398 lr_coeffs => donor_state%sf_coeffs
3401 CASE (tddfpt_singlet)
3402 lr_evals => donor_state%sg_evals
3403 lr_coeffs => donor_state%sg_coeffs
3406 CASE (tddfpt_triplet)
3407 lr_evals => donor_state%tp_evals
3408 lr_coeffs => donor_state%tp_coeffs
3413 SELECT CASE (donor_state%state_type)
3422 ndo_mo = donor_state%ndo_mo
3423 nex =
SIZE(lr_evals)
3424 CALL cp_fm_get_info(lr_coeffs, nrow_global=nao)
3425 state_type = donor_state%state_type
3426 ex_atom = donor_state%at_index
3427 mo_indices => donor_state%mo_indices
3431 my_middle =
'xasat'//trim(adjustl(cp_to_string(ex_atom)))//
'_'//trim(domo)//
'_'//trim(excite)
3432 rst_unit = cp_print_key_unit_nr(logger, xas_tdp_section,
"PRINT%RESTART", extension=
".rst", &
3433 file_status=
"REPLACE", file_action=
"WRITE", &
3434 file_form=
"UNFORMATTED", middle_name=trim(my_middle))
3436 filename = cp_print_key_generate_filename(logger, print_key, middle_name=trim(my_middle), &
3437 extension=
".rst", my_local=.false.)
3439 IF (output_unit > 0)
THEN
3440 WRITE (unit=output_unit, fmt=
"(/,T5,A,/T5,A,A,A)") &
3441 "Linear-response orbitals and excitation energies are written in: ", &
3442 '"', trim(filename),
'"'
3446 IF (rst_unit > 0)
THEN
3447 WRITE (rst_unit) ex_atom, state_type, ndo_mo, ex_type
3448 WRITE (rst_unit) nao, nex, nspins
3449 WRITE (rst_unit) mo_indices(:, :)
3450 WRITE (rst_unit) lr_evals(:)
3452 CALL cp_fm_write_unformatted(lr_coeffs, rst_unit)
3455 CALL get_qs_env(qs_env, mos=mos)
3456 DO ispin = 1, nspins
3457 CALL cp_fm_write_unformatted(mos(ispin)%mo_coeff, rst_unit)
3461 CALL cp_print_key_finished_output(rst_unit, logger, xas_tdp_section,
"PRINT%RESTART")
3463 CALL timestop(handle)
3465 END SUBROUTINE write_donor_state_restart
3474 SUBROUTINE read_donor_state_restart(donor_state, ex_type, filename, qs_env)
3476 TYPE(donor_state_type),
POINTER :: donor_state
3477 INTEGER,
INTENT(OUT) :: ex_type
3478 CHARACTER(len=*),
INTENT(IN) :: filename
3479 TYPE(qs_environment_type),
POINTER :: qs_env
3481 CHARACTER(len=*),
PARAMETER :: routinen =
'read_donor_state_restart'
3483 INTEGER :: handle, ispin, nao, nex, nspins, &
3484 output_unit, read_params(7), rst_unit
3485 INTEGER,
DIMENSION(:, :),
POINTER :: mo_indices
3486 LOGICAL :: file_exists
3487 REAL(dp),
DIMENSION(:),
POINTER :: lr_evals
3488 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
3489 TYPE(cp_fm_struct_type),
POINTER :: fm_struct
3490 TYPE(cp_fm_type),
POINTER :: lr_coeffs
3491 TYPE(mo_set_type),
DIMENSION(:),
POINTER :: mos
3492 TYPE(mp_comm_type) :: group
3493 TYPE(mp_para_env_type),
POINTER :: para_env
3495 NULLIFY (lr_evals, lr_coeffs, para_env, fm_struct, blacs_env, mos)
3497 CALL timeset(routinen, handle)
3499 output_unit = cp_logger_get_default_io_unit()
3500 cpassert(
ASSOCIATED(donor_state))
3501 CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
3504 file_exists = .false.
3507 IF (para_env%is_source())
THEN
3509 INQUIRE (file=filename, exist=file_exists)
3510 IF (.NOT. file_exists) cpabort(
"Trying to read non-existing XAS_TDP restart file")
3512 CALL open_file(file_name=trim(filename), file_action=
"READ", file_form=
"UNFORMATTED", &
3513 file_position=
"REWIND", file_status=
"OLD", unit_number=rst_unit)
3516 IF (output_unit > 0)
THEN
3517 WRITE (unit=output_unit, fmt=
"(/,T5,A,/,T5,A,A,A)") &
3518 "Reading linear-response orbitals and excitation energies from file: ", &
3523 IF (rst_unit > 0)
THEN
3524 READ (rst_unit) read_params(1:4)
3525 READ (rst_unit) read_params(5:7)
3527 CALL group%bcast(read_params)
3528 donor_state%at_index = read_params(1)
3529 donor_state%state_type = read_params(2)
3530 donor_state%ndo_mo = read_params(3)
3531 ex_type = read_params(4)
3532 nao = read_params(5)
3533 nex = read_params(6)
3534 nspins = read_params(7)
3536 ALLOCATE (mo_indices(donor_state%ndo_mo, nspins))
3537 IF (rst_unit > 0)
THEN
3538 READ (rst_unit) mo_indices(1:donor_state%ndo_mo, 1:nspins)
3540 CALL group%bcast(mo_indices)
3541 donor_state%mo_indices => mo_indices
3544 ALLOCATE (lr_evals(nex))
3545 IF (rst_unit > 0)
READ (rst_unit) lr_evals(1:nex)
3546 CALL group%bcast(lr_evals)
3549 CALL cp_fm_struct_create(fm_struct, context=blacs_env, para_env=para_env, &
3550 nrow_global=nao, ncol_global=nex*donor_state%ndo_mo*nspins)
3551 ALLOCATE (lr_coeffs)
3552 CALL cp_fm_create(lr_coeffs, fm_struct)
3553 CALL cp_fm_read_unformatted(lr_coeffs, rst_unit)
3554 CALL cp_fm_struct_release(fm_struct)
3557 CALL get_qs_env(qs_env, mos=mos)
3558 DO ispin = 1, nspins
3559 CALL cp_fm_read_unformatted(mos(ispin)%mo_coeff, rst_unit)
3563 IF (para_env%is_source())
THEN
3564 CALL close_file(unit_number=rst_unit)
3568 SELECT CASE (ex_type)
3569 CASE (tddfpt_spin_cons)
3570 donor_state%sc_evals => lr_evals
3571 donor_state%sc_coeffs => lr_coeffs
3572 CASE (tddfpt_spin_flip)
3573 donor_state%sf_evals => lr_evals
3574 donor_state%sf_coeffs => lr_coeffs
3575 CASE (tddfpt_singlet)
3576 donor_state%sg_evals => lr_evals
3577 donor_state%sg_coeffs => lr_coeffs
3578 CASE (tddfpt_triplet)
3579 donor_state%tp_evals => lr_evals
3580 donor_state%tp_coeffs => lr_coeffs
3583 CALL timestop(handle)
3585 END SUBROUTINE read_donor_state_restart
3593 SUBROUTINE restart_calculation(rst_filename, xas_tdp_section, qs_env)
3595 CHARACTER(len=*),
INTENT(IN) :: rst_filename
3596 TYPE(section_vals_type),
POINTER :: xas_tdp_section
3597 TYPE(qs_environment_type),
POINTER :: qs_env
3600 TYPE(donor_state_type),
POINTER :: donor_state
3601 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
3603 NULLIFY (xas_tdp_env, donor_state)
3606 ALLOCATE (donor_state)
3607 CALL donor_state_create(donor_state)
3608 CALL read_donor_state_restart(donor_state, ex_type, rst_filename, qs_env)
3611 CALL xas_tdp_env_create(xas_tdp_env)
3612 CALL xas_tdp_post(ex_type, donor_state, xas_tdp_env, xas_tdp_section, qs_env)
3615 CALL xas_tdp_env_release(xas_tdp_env)
3616 CALL free_ds_memory(donor_state)
3617 DEALLOCATE (donor_state%mo_indices)
3618 DEALLOCATE (donor_state)
3620 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)
...
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 create_gto_from_sto_basis(sto_basis_set, gto_basis_set, ngauss, ortho)
...
subroutine, public set_sto_basis_set(sto_basis_set, name, nshell, symbol, nq, lq, zet)
...
subroutine, public init_orb_basis_set(gto_basis_set)
Initialise a Gaussian-type orbital (GTO) basis set data set.
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.
DBCSR operations in CP2K.
subroutine, public cp_dbcsr_sm_fm_multiply(matrix, fm_in, fm_out, ncol, alpha, beta)
multiply a dbcsr with a fm matrix
subroutine, public copy_dbcsr_to_fm(matrix, fm)
Copy a DBCSR matrix to a BLACS matrix.
subroutine, public copy_fm_to_dbcsr(fm, matrix, keep_sparsity)
Copy a BLACS matrix to a dbcsr matrix.
Utility routines to open and close files. Tracking of preconnections.
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
Basic linear algebra operations for full matrices.
subroutine, public cp_fm_column_scale(matrixa, scaling)
scales column i of matrix a with scaling(i)
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 Single option version: Cholesky decomposition of B.
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_get_diag(matrix, diag)
returns the diagonal elements of a fm
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_write_unformatted(fm, unit)
...
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_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,...
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer, parameter, public debug_print_level
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
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...
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
integer, parameter, public default_path_length
Interface to the Libint-Library or a c++ wrapper.
subroutine, public cp_libint_static_init()
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)
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
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, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
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, 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, 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 centers_spreads_berry(qs_loc_env, zij, nmoloc, cell, weights, ispin, print_loc_section, only_initial_out)
...
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
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 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)
Get the components of a MO set data structure.
subroutine, public init_mo_set(mo_set, fm_pool, fm_ref, fm_struct, name)
initializes an allocated mo_set. eigenvalues, mo_coeff, occupation_numbers are valid only after this ...
subroutine, public p_xyz_ao(op, qs_env, minimum_image)
Calculation of the components of the dipole operator in the velocity form The elements of the sparse ...
subroutine, public rrc_xyz_ao(op, qs_env, rc, order, minimum_image, soft)
Calculation of the components of the dipole operator in the length form by taking the relative positi...
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)
Compute and write projected density of states.
superstucture that hold various representations of the density and keeps track of which ones are vali...
subroutine, public qs_rho_get(rho_struct, rho_ao, rho_ao_im, rho_ao_kp, rho_ao_im_kp, rho_r, drho_r, rho_g, drho_g, tau_r, tau_g, rho_r_valid, drho_r_valid, rho_g_valid, drho_g_valid, tau_r_valid, tau_g_valid, tot_rho_r, tot_rho_g, rho_r_sccs, soft_valid, complex_rho_ao)
returns info about the density described by this object. If some representation is not available an e...
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...
keeps the density in various representations, keeping track of which ones are valid.
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.