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) .NE. 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 .NE.
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 .NE. 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)
1082 IF (ou .LE. 0)
RETURN
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:"
1160 CALL xc_write(ou, kernel_section, lsd=.true.)
1164 IF (xas_tdp_control%do_hfx)
THEN
1165 WRITE (unit=ou, fmt=
"(/,T3,A,/,/,T3,A,F5.3)") &
1166 "XAS_TDP| Exact Exchange Kernel: Yes ", &
1167 "EXACT_EXCHANGE| Scale: ", xas_tdp_control%sx
1169 WRITE (unit=ou, fmt=
"(T3,A)") &
1170 "EXACT_EXCHANGE| Potential : Coulomb"
1172 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,A)") &
1173 "EXACT_EXCHANGE| Potential: Truncated Coulomb", &
1174 "EXACT_EXCHANGE| Range: ", xas_tdp_control%x_potential%cutoff_radius*
angstrom,
", (Ang)", &
1175 "EXACT_EXCHANGE| T_C_G_DATA: ", trim(xas_tdp_control%x_potential%filename)
1177 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,F5.2,A,/,T3,A,ES7.1)") &
1178 "EXACT_EXCHANGE| Potential: Short Range", &
1179 "EXACT_EXCHANGE| Omega: ", xas_tdp_control%x_potential%omega,
", (1/a0)", &
1180 "EXACT_EXCHANGE| Effective Range: ", xas_tdp_control%x_potential%cutoff_radius*
angstrom,
", (Ang)", &
1181 "EXACT_EXCHANGE| EPS_RANGE: ", xas_tdp_control%eps_range
1183 IF (xas_tdp_control%eps_screen > 1.0e-16)
THEN
1184 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1185 "EXACT_EXCHANGE| EPS_SCREENING: ", xas_tdp_control%eps_screen
1189 IF (xas_tdp_control%do_ri_metric)
THEN
1191 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1192 "EXACT_EXCHANGE| Using a RI metric"
1193 IF (xas_tdp_control%ri_m_potential%potential_type ==
do_potential_id)
THEN
1194 WRITE (unit=ou, fmt=
"(T3,A)") &
1195 "EXACT_EXCHANGE RI_METRIC| Potential : Overlap"
1197 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,A)") &
1198 "EXACT_EXCHANGE RI_METRIC| Potential: Truncated Coulomb", &
1199 "EXACT_EXCHANGE RI_METRIC| Range: ", xas_tdp_control%ri_m_potential%cutoff_radius &
1201 "EXACT_EXCHANGE RI_METRIC| T_C_G_DATA: ", trim(xas_tdp_control%ri_m_potential%filename)
1203 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,F5.2,A,/,T3,A,ES7.1)") &
1204 "EXACT_EXCHANGE RI_METRIC| Potential: Short Range", &
1205 "EXACT_EXCHANGE RI_METRIC| Omega: ", xas_tdp_control%ri_m_potential%omega,
", (1/a0)", &
1206 "EXACT_EXCHANGE RI_METRIC| Effective Range: ", &
1207 xas_tdp_control%ri_m_potential%cutoff_radius*
angstrom,
", (Ang)", &
1208 "EXACT_EXCHANGE RI_METRIC| EPS_RANGE: ", xas_tdp_control%eps_range
1212 WRITE (unit=ou, fmt=
"(/,T3,A,/)") &
1213 "XAS_TDP| Exact Exchange Kernel: No "
1217 WRITE (unit=ou, fmt=
"(/,T3,A,F5.2)") &
1218 "XAS_TDP| Overlap matrix occupation: ", occ
1221 IF (xas_tdp_control%do_gw2x)
THEN
1222 WRITE (unit=ou, fmt=
"(T3,A,/)") &
1223 "XAS_TDP| GW2X correction enabled"
1225 IF (xas_tdp_control%xps_only)
THEN
1226 WRITE (unit=ou, fmt=
"(T3,A)") &
1227 "GW2X| Only computing ionizations potentials for XPS"
1230 IF (xas_tdp_control%pseudo_canonical)
THEN
1231 WRITE (unit=ou, fmt=
"(T3,A)") &
1232 "GW2X| Using the pseudo-canonical scheme"
1234 WRITE (unit=ou, fmt=
"(T3,A)") &
1235 "GW2X| Using the GW2X* scheme"
1238 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1239 "GW2X| EPS_GW2X: ", xas_tdp_control%gw2x_eps
1241 WRITE (unit=ou, fmt=
"(T3,A,I5)") &
1242 "GW2X| contraction batch size: ", xas_tdp_control%batch_size
1244 IF ((int(xas_tdp_control%c_os) .NE. 1) .OR. (int(xas_tdp_control%c_ss) .NE. 1))
THEN
1245 WRITE (unit=ou, fmt=
"(T3,A,F7.4,/,T3,A,F7.4)") &
1246 "GW2X| Same-spin scaling factor: ", xas_tdp_control%c_ss, &
1247 "GW2X| Opposite-spin scaling factor: ", xas_tdp_control%c_os
1252 END SUBROUTINE print_info
1267 SUBROUTINE assign_mos_to_ex_atoms(xas_tdp_env, xas_tdp_control, qs_env)
1273 INTEGER :: at_index, iat, iat_memo, imo, ispin, &
1274 n_atoms, n_search, nex_atoms, nspins
1275 INTEGER,
DIMENSION(3) :: perd_init
1276 INTEGER,
DIMENSION(:, :, :),
POINTER :: mos_of_ex_atoms
1277 REAL(
dp) :: dist, dist_min
1278 REAL(
dp),
DIMENSION(3) :: at_pos, r_ac, wfn_center
1283 NULLIFY (localized_wfn_control, mos_of_ex_atoms, cell, particle_set)
1286 mos_of_ex_atoms => xas_tdp_env%mos_of_ex_atoms
1287 mos_of_ex_atoms(:, :, :) = -1
1288 n_search = xas_tdp_control%n_search
1289 nex_atoms = xas_tdp_env%nex_atoms
1290 localized_wfn_control => xas_tdp_env%qs_loc_env%localized_wfn_control
1291 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, cell=cell)
1292 n_atoms =
SIZE(particle_set)
1293 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1296 perd_init = cell%perd
1300 DO ispin = 1, nspins
1301 DO imo = 1, n_search
1303 wfn_center(1:3) = localized_wfn_control%centers_set(ispin)%array(1:3, imo)
1307 dist_min = 10000.0_dp
1309 at_pos = particle_set(iat)%r
1310 r_ac =
pbc(at_pos, wfn_center, cell)
1314 IF (dist < dist_min)
THEN
1321 IF (any(xas_tdp_env%ex_atom_indices == iat_memo))
THEN
1322 at_index =
locate(xas_tdp_env%ex_atom_indices, iat_memo)
1323 mos_of_ex_atoms(imo, at_index, ispin) = 1
1329 cell%perd = perd_init
1331 END SUBROUTINE assign_mos_to_ex_atoms
1343 SUBROUTINE reinit_qs_loc_env(qs_loc_env, n_loc_states, do_uks, qs_env)
1346 INTEGER,
INTENT(IN) :: n_loc_states
1347 LOGICAL,
INTENT(IN) :: do_uks
1350 INTEGER :: i, nspins
1359 loc_wfn_control => qs_loc_env%localized_wfn_control
1364 loc_wfn_control%nloc_states(:) = n_loc_states
1365 loc_wfn_control%eps_occ = 0.0_dp
1366 loc_wfn_control%lu_bound_states(1, :) = 1
1367 loc_wfn_control%lu_bound_states(2, :) = n_loc_states
1369 loc_wfn_control%do_homo = .true.
1370 ALLOCATE (loc_wfn_control%loc_states(n_loc_states, 2))
1371 DO i = 1, n_loc_states
1372 loc_wfn_control%loc_states(i, :) = i
1375 nspins = 1;
IF (do_uks) nspins = 2
1376 CALL set_loc_centers(loc_wfn_control, loc_wfn_control%nloc_states, nspins=nspins)
1379 CALL qs_loc_env_init(qs_loc_env, loc_wfn_control, qs_env, do_localize=.true.)
1381 CALL qs_loc_env_init(qs_loc_env, loc_wfn_control, qs_env, myspin=1, do_localize=.true.)
1384 END SUBROUTINE reinit_qs_loc_env
1394 SUBROUTINE diagonalize_assigned_mo_subset(xas_tdp_env, xas_tdp_control, qs_env)
1400 INTEGER :: i, iat, ilmo, ispin, nao, nlmo, nspins
1401 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: evals
1404 TYPE(
cp_fm_type) :: evecs, ks_fm, lmo_fm, work
1410 NULLIFY (mos, mo_coeff, matrix_ks, para_env, blacs_env, lmo_struct, ks_struct)
1413 CALL get_qs_env(qs_env, mos=mos, matrix_ks=matrix_ks, para_env=para_env, blacs_env=blacs_env)
1415 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1418 DO ispin = 1, nspins
1419 DO iat = 1, xas_tdp_env%nex_atoms
1422 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, nao=nao)
1425 nlmo = count(xas_tdp_env%mos_of_ex_atoms(:, iat, ispin) == 1)
1427 para_env=para_env, context=blacs_env)
1432 para_env=para_env, context=blacs_env)
1438 DO ilmo = 1, xas_tdp_control%n_search
1439 IF (xas_tdp_env%mos_of_ex_atoms(ilmo, iat, ispin) == -1) cycle
1444 s_firstcol=ilmo, t_firstrow=1, t_firstcol=i)
1450 CALL parallel_gemm(
'T',
'N', nlmo, nlmo, nao, 1.0_dp, lmo_fm, work, 0.0_dp, ks_fm)
1453 ALLOCATE (evals(nlmo))
1458 CALL parallel_gemm(
'N',
'N', nao, nlmo, nlmo, 1.0_dp, lmo_fm, evecs, 0.0_dp, work)
1462 DO ilmo = 1, xas_tdp_control%n_search
1463 IF (xas_tdp_env%mos_of_ex_atoms(ilmo, iat, ispin) == -1) cycle
1467 s_firstcol=i, t_firstrow=1, t_firstcol=ilmo)
1481 END SUBROUTINE diagonalize_assigned_mo_subset
1492 SUBROUTINE assign_mos_to_donor_state(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
1499 INTEGER :: at_index, i, iat, imo, ispin, l, my_mo, &
1500 n_search, n_states, nao, ndo_so, nj, &
1501 nsgf_kind, nsgf_sto, nspins, &
1503 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: my_mos
1504 INTEGER,
DIMENSION(2) :: next_best_overlap_ind
1505 INTEGER,
DIMENSION(4, 7) :: ne
1506 INTEGER,
DIMENSION(:),
POINTER :: first_sgf, lq, nq
1507 INTEGER,
DIMENSION(:, :, :),
POINTER :: mos_of_ex_atoms
1510 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) ::
diag, overlap, sto_overlap
1511 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: max_overlap
1512 REAL(
dp),
DIMENSION(2) :: next_best_overlap
1513 REAL(
dp),
DIMENSION(:),
POINTER :: mo_evals, zeta
1514 REAL(
dp),
DIMENSION(:, :),
POINTER :: overlap_matrix, tmp_coeff
1518 TYPE(
cp_fm_type),
POINTER :: gs_coeffs, mo_coeff
1524 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
1527 NULLIFY (sto_basis_set, sto_to_gto_basis_set, qs_kind_set, kind_basis_set, lq, nq, zeta)
1528 NULLIFY (overlap_matrix, mos, mo_coeff, mos_of_ex_atoms, tmp_coeff, first_sgf, particle_set)
1529 NULLIFY (mo_evals, matrix_ks, para_env, blacs_env)
1530 NULLIFY (eval_mat_struct, gs_struct, gs_coeffs)
1534 CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set, mos=mos, particle_set=particle_set, &
1535 matrix_ks=matrix_ks, para_env=para_env, blacs_env=blacs_env)
1537 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1548 ELSE IF (donor_state%state_type ==
xas_2s_type)
THEN
1552 ELSE IF (donor_state%state_type ==
xas_2p_type)
THEN
1557 cpabort(
"Procedure for required type not implemented")
1559 ALLOCATE (my_mos(n_states, nspins))
1560 ALLOCATE (max_overlap(n_states, nspins))
1563 CALL get_qs_kind(qs_kind_set(donor_state%kind_index), zeff=zeff)
1571 ne(l, i) =
ptable(zval)%e_conv(l - 1) - 2*nj*(i - l)
1572 ne(l, i) = max(ne(l, i), 0)
1573 ne(l, i) = min(ne(l, i), 2*nj)
1578 zeta(1) =
srules(zval, ne, nq(1), lq(1))
1585 DEALLOCATE (nq, lq, zeta)
1589 gto_basis_set=sto_to_gto_basis_set, &
1591 sto_to_gto_basis_set%norm_type = 2
1595 CALL get_qs_kind(qs_kind_set(donor_state%kind_index), basis_set=kind_basis_set)
1600 ALLOCATE (overlap_matrix(nsgf_sto, nsgf_kind))
1610 mos_of_ex_atoms => xas_tdp_env%mos_of_ex_atoms
1611 n_search = xas_tdp_control%n_search
1612 at_index = donor_state%at_index
1613 iat =
locate(xas_tdp_env%ex_atom_indices, at_index)
1614 ALLOCATE (first_sgf(
SIZE(particle_set)))
1615 CALL get_particle_set(particle_set=particle_set, qs_kind_set=qs_kind_set, first_sgf=first_sgf)
1616 ALLOCATE (tmp_coeff(nsgf_kind, 1))
1617 ALLOCATE (sto_overlap(nsgf_kind))
1618 ALLOCATE (overlap(n_search))
1620 next_best_overlap = 0.0_dp
1621 max_overlap = 0.0_dp
1623 DO ispin = 1, nspins
1625 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, nao=nao)
1629 DO imo = 1, n_search
1630 IF (mos_of_ex_atoms(imo, iat, ispin) > 0)
THEN
1632 sto_overlap = 0.0_dp
1636 CALL cp_fm_get_submatrix(fm=mo_coeff, target_m=tmp_coeff, start_row=first_sgf(at_index), &
1637 start_col=imo, n_rows=nsgf_kind, n_cols=1, transpose=.false.)
1640 CALL dgemm(
'N',
'N', nsgf_sto, 1, nsgf_kind, 1.0_dp, overlap_matrix, nsgf_sto, &
1641 tmp_coeff, nsgf_kind, 0.0_dp, sto_overlap, nsgf_sto)
1646 overlap(imo) = sum(abs(sto_overlap))
1653 my_mo = maxloc(overlap, 1)
1654 my_mos(i, ispin) = my_mo
1655 max_overlap(i, ispin) = maxval(overlap, 1)
1656 overlap(my_mo) = 0.0_dp
1659 next_best_overlap(ispin) = maxval(overlap, 1)
1660 next_best_overlap_ind(ispin) = maxloc(overlap, 1)
1668 DEALLOCATE (overlap_matrix, tmp_coeff)
1671 IF (all(my_mos > 0) .AND. all(my_mos <= n_search))
THEN
1673 ALLOCATE (donor_state%mo_indices(n_states, nspins))
1674 donor_state%mo_indices = my_mos
1675 donor_state%ndo_mo = n_states
1679 para_env=para_env, context=blacs_env)
1680 ALLOCATE (donor_state%gs_coeffs)
1683 IF (.NOT.
ASSOCIATED(xas_tdp_env%mo_coeff))
THEN
1684 ALLOCATE (xas_tdp_env%mo_coeff(nspins))
1687 DO ispin = 1, nspins
1688 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff)
1690 IF (.NOT.
ASSOCIATED(xas_tdp_env%mo_coeff(ispin)%local_data))
THEN
1693 matrix_struct=matrix_struct)
1694 CALL cp_fm_create(xas_tdp_env%mo_coeff(ispin), matrix_struct)
1695 CALL cp_fm_to_fm(mo_coeff, xas_tdp_env%mo_coeff(ispin))
1700 ncol=1, s_firstrow=1, s_firstcol=my_mos(i, ispin), &
1701 t_firstrow=1, t_firstcol=(ispin - 1)*n_states + i)
1704 gs_coeffs => donor_state%gs_coeffs
1707 ALLOCATE (donor_state%contract_coeffs(nsgf_kind, n_states*nspins))
1708 CALL cp_fm_get_submatrix(gs_coeffs, donor_state%contract_coeffs, start_row=first_sgf(at_index), &
1709 start_col=1, n_rows=nsgf_kind, n_cols=n_states*nspins)
1714 IF (.NOT. xas_tdp_control%do_loc .AND. .NOT. xas_tdp_control%do_roks)
THEN
1715 IF (output_unit > 0)
THEN
1716 WRITE (unit=output_unit, fmt=
"(T5,A,/,T5,A,/,T5,A)") &
1717 "The following canonical MO(s) have been associated with the donor state(s)", &
1718 "based on the overlap with the components of a minimal STO basis: ", &
1719 " Spin MO index overlap(sum)"
1722 ALLOCATE (donor_state%energy_evals(n_states, nspins))
1723 donor_state%energy_evals = 0.0_dp
1726 DO ispin = 1, nspins
1727 CALL get_mo_set(mos(ispin), eigenvalues=mo_evals)
1729 donor_state%energy_evals(i, ispin) = mo_evals(my_mos(i, ispin))
1731 IF (output_unit > 0)
THEN
1732 WRITE (unit=output_unit, fmt=
"(T46,I4,I11,F17.5)") &
1733 ispin, my_mos(i, ispin), max_overlap(i, ispin)
1741 IF (output_unit > 0)
THEN
1742 WRITE (unit=output_unit, fmt=
"(T5,A,/,T5,A,/,T5,A)") &
1743 "The following localized MO(s) have been associated with the donor state(s)", &
1744 "based on the overlap with the components of a minimal STO basis: ", &
1745 " Spin MO index overlap(sum)"
1749 DO ispin = 1, nspins
1753 IF (output_unit > 0)
THEN
1754 WRITE (unit=output_unit, fmt=
"(T46,I4,I11,F17.5)") &
1755 ispin, my_mos(i, ispin), max_overlap(i, ispin)
1763 ndo_so = nspins*n_states
1766 para_env=para_env, context=blacs_env)
1768 ALLOCATE (
diag(ndo_so))
1770 IF (.NOT. xas_tdp_control%do_roks)
THEN
1772 ALLOCATE (donor_state%energy_evals(n_states, nspins))
1773 donor_state%energy_evals = 0.0_dp
1776 DO ispin = 1, nspins
1778 CALL parallel_gemm(
'T',
'N', ndo_so, ndo_so, nao, 1.0_dp, gs_coeffs, work_mat, 0.0_dp, eval_mat)
1782 donor_state%energy_evals(:, ispin) =
diag((ispin - 1)*n_states + 1:ispin*n_states)
1788 ALLOCATE (donor_state%energy_evals(n_states, 2))
1789 donor_state%energy_evals = 0.0_dp
1794 CALL parallel_gemm(
'T',
'N', ndo_so, ndo_so, nao, 1.0_dp, gs_coeffs, work_mat, 0.0_dp, eval_mat)
1797 donor_state%energy_evals(:, ispin) =
diag(:)
1812 ALLOCATE (donor_state%gw2x_evals(
SIZE(donor_state%energy_evals, 1),
SIZE(donor_state%energy_evals, 2)))
1813 donor_state%gw2x_evals(:, :) = donor_state%energy_evals(:, :)
1817 DEALLOCATE (first_sgf)
1819 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T5,A)")
" "
1821 DO ispin = 1, nspins
1822 IF (output_unit > 0)
THEN
1823 WRITE (unit=output_unit, fmt=
"(T5,A,I1,A,F7.5,A,I4)") &
1824 "The next best overlap for spin ", ispin,
" is ", next_best_overlap(ispin), &
1825 " for MO with index ", next_best_overlap_ind(ispin)
1828 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T5,A)")
" "
1831 cpabort(
"A core donor state could not be assigned MO(s). Increasing NSEARCH might help.")
1834 END SUBROUTINE assign_mos_to_donor_state
1844 SUBROUTINE find_mo_centers(xas_tdp_env, xas_tdp_control, qs_env)
1850 INTEGER :: dim_op, i, ispin, j, n_centers, nao, &
1852 REAL(
dp),
DIMENSION(6) :: weights
1857 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:, :) :: zij_fm_set
1858 TYPE(
cp_fm_type),
DIMENSION(:),
POINTER :: moloc_coeff
1860 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: op_sm_set
1865 NULLIFY (qs_loc_env, cell, print_loc_section, op_sm_set, moloc_coeff, vectors)
1866 NULLIFY (tmp_fm_struct, para_env, blacs_env, prog_run_info)
1869 print_loc_section => xas_tdp_control%print_loc_subsection
1870 n_centers = xas_tdp_control%n_search
1871 CALL get_qs_env(qs_env=qs_env, para_env=para_env, blacs_env=blacs_env, cell=cell)
1879 CALL reinit_qs_loc_env(xas_tdp_env%qs_loc_env, n_centers, xas_tdp_control%do_uks, qs_env)
1880 qs_loc_env => xas_tdp_env%qs_loc_env
1883 CALL get_qs_loc_env(qs_loc_env=qs_loc_env, weights=weights, op_sm_set=op_sm_set, &
1884 moloc_coeff=moloc_coeff)
1887 vectors => moloc_coeff(1)
1892 ncol_global=n_centers, nrow_global=n_centers)
1894 IF (cell%orthorhombic)
THEN
1899 ALLOCATE (zij_fm_set(2, dim_op))
1907 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1909 DO ispin = 1, nspins
1911 vectors => moloc_coeff(ispin)
1916 CALL parallel_gemm(
"T",
"N", n_centers, n_centers, nao, 1.0_dp, vectors, opvec, 0.0_dp, &
1923 cell=cell, weights=weights, ispin=ispin, &
1924 print_loc_section=print_loc_section, only_initial_out=.true.)
1933 qs_loc_env%do_localize = xas_tdp_control%do_loc
1935 END SUBROUTINE find_mo_centers
1944 SUBROUTINE print_checks(xas_tdp_env, xas_tdp_control, qs_env)
1950 CHARACTER(LEN=default_string_length) :: kind_name
1951 INTEGER :: current_state_index, iat, iatom, ikind, &
1952 istate, output_unit, tmp_index
1953 INTEGER,
DIMENSION(:),
POINTER :: atoms_of_kind
1957 NULLIFY (atomic_kind_set, atoms_of_kind, current_state)
1961 IF (output_unit > 0)
THEN
1962 WRITE (output_unit,
"(/,T3,A,/,T3,A,/,T3,A)") &
1963 "# Check the donor states for their quality. They need to have a well defined type ", &
1964 " (1s, 2s, etc) which is indicated by the overlap. They also need to be localized, ", &
1965 " for which the Mulliken population analysis is one indicator (must be close to 1.0)"
1969 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
1970 current_state_index = 1
1973 DO ikind = 1,
SIZE(atomic_kind_set)
1975 CALL get_atomic_kind(atomic_kind=atomic_kind_set(ikind), name=kind_name, &
1976 atom_list=atoms_of_kind)
1978 IF (.NOT. any(xas_tdp_env%ex_kind_indices == ikind)) cycle
1981 DO iat = 1,
SIZE(atoms_of_kind)
1982 iatom = atoms_of_kind(iat)
1984 IF (.NOT. any(xas_tdp_env%ex_atom_indices == iatom)) cycle
1985 tmp_index =
locate(xas_tdp_env%ex_atom_indices, iatom)
1988 DO istate = 1,
SIZE(xas_tdp_env%state_types, 1)
1990 IF (xas_tdp_env%state_types(istate, tmp_index) ==
xas_not_excited) cycle
1992 current_state => xas_tdp_env%donor_states(current_state_index)
1994 at_symbol=kind_name, kind_index=ikind, &
1995 state_type=xas_tdp_env%state_types(istate, tmp_index))
1997 IF (output_unit > 0)
THEN
1998 WRITE (output_unit,
"(/,T4,A,A2,A,I4,A,A,A)") &
1999 "-Donor state of type ", xas_tdp_env%state_type_char(current_state%state_type), &
2000 " for atom", current_state%at_index,
" of kind ", trim(current_state%at_symbol),
":"
2004 CALL assign_mos_to_donor_state(current_state, xas_tdp_env, xas_tdp_control, qs_env)
2005 CALL perform_mulliken_on_donor_state(current_state, qs_env)
2007 current_state_index = current_state_index + 1
2008 NULLIFY (current_state)
2014 IF (output_unit > 0)
THEN
2015 WRITE (output_unit,
"(/,T5,A)") &
2016 "Use LOCALIZE and/or increase N_SEARCH for better results, if so required."
2019 END SUBROUTINE print_checks
2029 SUBROUTINE compute_lenrep_multipole(iatom, xas_tdp_env, xas_tdp_control, qs_env)
2031 INTEGER,
INTENT(IN) :: iatom
2037 REAL(
dp),
DIMENSION(3) :: rc
2041 NULLIFY (work, particle_set)
2043 CALL get_qs_env(qs_env, particle_set=particle_set)
2044 rc = particle_set(iatom)%r
2047 IF (xas_tdp_control%dipole_form ==
xas_dip_len)
THEN
2049 CALL dbcsr_set(xas_tdp_env%dipmat(i)%matrix, 0.0_dp)
2050 work(i)%matrix => xas_tdp_env%dipmat(i)%matrix
2054 IF (xas_tdp_control%do_quad)
THEN
2056 CALL dbcsr_set(xas_tdp_env%quadmat(i)%matrix, 0.0_dp)
2057 work(3 + i)%matrix => xas_tdp_env%quadmat(i)%matrix
2060 IF (xas_tdp_control%dipole_form ==
xas_dip_vel) order = -2
2064 CALL rrc_xyz_ao(work, qs_env, rc, order=order, minimum_image=.true.)
2067 END SUBROUTINE compute_lenrep_multipole
2081 SUBROUTINE compute_dipole_fosc(donor_state, xas_tdp_control, xas_tdp_env)
2087 CHARACTER(len=*),
PARAMETER :: routinen =
'compute_dipole_fosc'
2089 INTEGER :: handle, iosc, j, nao, ndo_mo, ndo_so, &
2091 LOGICAL :: do_sc, do_sg
2092 REAL(
dp) :: alpha_xyz, beta_xyz, osc_xyz, pref
2093 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: alpha_contr, beta_contr, tot_contr
2094 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: dip_block
2095 REAL(
dp),
DIMENSION(:),
POINTER :: lr_evals
2096 REAL(
dp),
DIMENSION(:, :),
POINTER :: alpha_osc, beta_osc, osc_str
2104 NULLIFY (dipmat, col_struct, mat_struct, para_env, blacs_env, lr_coeffs)
2105 NULLIFY (lr_evals, osc_str, alpha_osc, beta_osc)
2107 CALL timeset(routinen, handle)
2110 do_sc = xas_tdp_control%do_spin_cons
2111 do_sg = xas_tdp_control%do_singlet
2114 lr_evals => donor_state%sc_evals
2115 lr_coeffs => donor_state%sc_coeffs
2116 ELSE IF (do_sg)
THEN
2118 lr_evals => donor_state%sg_evals
2119 lr_coeffs => donor_state%sg_coeffs
2121 cpabort(
"Dipole oscilaltor strength only for singlets and spin-conserving excitations.")
2123 ndo_mo = donor_state%ndo_mo
2124 ndo_so = ndo_mo*nspins
2125 ngs = ndo_so;
IF (xas_tdp_control%do_roks) ngs = ndo_mo
2126 nosc =
SIZE(lr_evals)
2127 ALLOCATE (donor_state%osc_str(nosc, 4), donor_state%alpha_osc(nosc, 4), donor_state%beta_osc(nosc, 4))
2128 osc_str => donor_state%osc_str
2129 alpha_osc => donor_state%alpha_osc
2130 beta_osc => donor_state%beta_osc
2134 dipmat => xas_tdp_env%dipmat
2137 CALL cp_fm_get_info(donor_state%gs_coeffs, matrix_struct=col_struct, para_env=para_env, &
2138 context=blacs_env, nrow_global=nao)
2140 nrow_global=ndo_so*nosc, ncol_global=ngs)
2144 ALLOCATE (tot_contr(ndo_mo), dip_block(ndo_so, ngs), alpha_contr(ndo_mo), beta_contr(ndo_mo))
2145 pref = 2.0_dp;
IF (do_sc) pref = 1.0_dp
2153 CALL parallel_gemm(
'T',
'N', ndo_so*nosc, ngs, nao, 1.0_dp, lr_coeffs, col_work, 0.0_dp, mat_work)
2159 CALL cp_fm_get_submatrix(fm=mat_work, target_m=dip_block, start_row=(iosc - 1)*ndo_so + 1, &
2160 start_col=1, n_rows=ndo_so, n_cols=ngs)
2163 ELSE IF (do_sc .AND. xas_tdp_control%do_uks)
THEN
2164 alpha_contr(:) =
get_diag(dip_block(1:ndo_mo, 1:ndo_mo))
2165 beta_contr(:) =
get_diag(dip_block(ndo_mo + 1:ndo_so, ndo_mo + 1:ndo_so))
2166 tot_contr(:) = alpha_contr(:) + beta_contr(:)
2169 alpha_contr(:) =
get_diag(dip_block(1:ndo_mo, :))
2170 beta_contr(:) =
get_diag(dip_block(ndo_mo + 1:ndo_so, :))
2171 tot_contr(:) = alpha_contr(:) + beta_contr(:)
2174 osc_xyz = sum(tot_contr)**2
2175 alpha_xyz = sum(alpha_contr)**2
2176 beta_xyz = sum(beta_contr)**2
2178 alpha_osc(iosc, 4) = alpha_osc(iosc, 4) + alpha_xyz
2179 alpha_osc(iosc, j) = alpha_xyz
2181 beta_osc(iosc, 4) = beta_osc(iosc, 4) + beta_xyz
2182 beta_osc(iosc, j) = beta_xyz
2184 osc_str(iosc, 4) = osc_str(iosc, 4) + osc_xyz
2185 osc_str(iosc, j) = osc_xyz
2192 IF (xas_tdp_control%dipole_form ==
xas_dip_len)
THEN
2193 osc_str(:, j) = pref*2.0_dp/3.0_dp*lr_evals(:)*osc_str(:, j)
2194 alpha_osc(:, j) = pref*2.0_dp/3.0_dp*lr_evals(:)*alpha_osc(:, j)
2195 beta_osc(:, j) = pref*2.0_dp/3.0_dp*lr_evals(:)*beta_osc(:, j)
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)
2208 CALL timestop(handle)
2210 END SUBROUTINE compute_dipole_fosc
2220 SUBROUTINE compute_quadrupole_fosc(donor_state, xas_tdp_control, xas_tdp_env)
2226 CHARACTER(len=*),
PARAMETER :: routinen =
'compute_quadrupole_fosc'
2228 INTEGER :: handle, iosc, j, nao, ndo_mo, ndo_so, &
2230 LOGICAL :: do_sc, do_sg
2232 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: tot_contr, trace
2233 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: quad_block
2234 REAL(
dp),
DIMENSION(:),
POINTER :: lr_evals, osc_str
2242 NULLIFY (lr_evals, osc_str, lr_coeffs, col_struct, mat_struct, para_env)
2245 CALL timeset(routinen, handle)
2248 do_sc = xas_tdp_control%do_spin_cons
2249 do_sg = xas_tdp_control%do_singlet
2252 lr_evals => donor_state%sc_evals
2253 lr_coeffs => donor_state%sc_coeffs
2254 ELSE IF (do_sg)
THEN
2256 lr_evals => donor_state%sg_evals
2257 lr_coeffs => donor_state%sg_coeffs
2259 cpabort(
"Quadrupole oscillator strengths only for singlet and spin-conserving excitations")
2261 ndo_mo = donor_state%ndo_mo
2262 ndo_so = ndo_mo*nspins
2263 ngs = ndo_so;
IF (xas_tdp_control%do_roks) ngs = ndo_mo
2264 nosc =
SIZE(lr_evals)
2265 ALLOCATE (donor_state%quad_osc_str(nosc))
2266 osc_str => donor_state%quad_osc_str
2268 quadmat => xas_tdp_env%quadmat
2271 CALL cp_fm_get_info(donor_state%gs_coeffs, matrix_struct=col_struct, para_env=para_env, &
2272 context=blacs_env, nrow_global=nao)
2274 nrow_global=ndo_so*nosc, ncol_global=ngs)
2278 ALLOCATE (quad_block(ndo_so, ngs), tot_contr(ndo_mo))
2279 pref = 2.0_dp;
IF (do_sc) pref = 1.0_dp
2280 ALLOCATE (trace(nosc))
2289 CALL parallel_gemm(
'T',
'N', ndo_so*nosc, ngs, nao, 1.0_dp, lr_coeffs, col_work, 0.0_dp, mat_work)
2295 CALL cp_fm_get_submatrix(fm=mat_work, target_m=quad_block, start_row=(iosc - 1)*ndo_so + 1, &
2296 start_col=1, n_rows=ndo_so, n_cols=ngs)
2299 tot_contr(:) =
get_diag(quad_block)
2300 ELSE IF (do_sc .AND. xas_tdp_control%do_uks)
THEN
2301 tot_contr(:) =
get_diag(quad_block(1:ndo_mo, 1:ndo_mo))
2302 tot_contr(:) = tot_contr(:) +
get_diag(quad_block(ndo_mo + 1:ndo_so, ndo_mo + 1:ndo_so))
2305 tot_contr(:) =
get_diag(quad_block(1:ndo_mo, :))
2306 tot_contr(:) = tot_contr(:) +
get_diag(quad_block(ndo_mo + 1:ndo_so, :))
2310 IF (j == 1 .OR. j == 4 .OR. j == 6)
THEN
2311 osc_str(iosc) = osc_str(iosc) + sum(tot_contr)**2
2312 trace(iosc) = trace(iosc) + sum(tot_contr)
2316 osc_str(iosc) = osc_str(iosc) + 2.0_dp*sum(tot_contr)**2
2323 osc_str(:) = pref*1._dp/20._dp*
a_fine**2*lr_evals(:)**3*(osc_str(:) - 1._dp/3._dp*trace(:)**2)
2330 CALL timestop(handle)
2332 END SUBROUTINE compute_quadrupole_fosc
2341 SUBROUTINE write_mos_to_ex_atoms_association(xas_tdp_env, xas_tdp_control, qs_env)
2347 CHARACTER(LEN=default_string_length) :: kind_name
2348 INTEGER :: at_index, imo, ispin, nmo, nspins, &
2349 output_unit, tmp_index
2350 INTEGER,
DIMENSION(3) :: perd_init
2351 INTEGER,
DIMENSION(:),
POINTER :: ex_atom_indices
2352 INTEGER,
DIMENSION(:, :, :),
POINTER :: mos_of_ex_atoms
2353 REAL(
dp) :: dist, mo_spread
2354 REAL(
dp),
DIMENSION(3) :: at_pos, r_ac, wfn_center
2358 NULLIFY (cell, particle_set, mos_of_ex_atoms, ex_atom_indices)
2362 IF (output_unit > 0)
THEN
2363 WRITE (unit=output_unit, fmt=
"(/,T3,A,/,T3,A,/,T3,A)") &
2364 " Associated Associated Distance to MO spread (Ang^2)", &
2365 "Spin MO index atom index atom kind MO center (Ang) -w_i ln(|z_ij|^2)", &
2366 "---------------------------------------------------------------------------------"
2370 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
2371 mos_of_ex_atoms => xas_tdp_env%mos_of_ex_atoms
2372 ex_atom_indices => xas_tdp_env%ex_atom_indices
2373 nmo = xas_tdp_control%n_search
2374 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, cell=cell)
2377 perd_init = cell%perd
2382 DO ispin = 1, nspins
2385 IF (any(mos_of_ex_atoms(imo, :, ispin) == 1))
THEN
2386 tmp_index = maxloc(mos_of_ex_atoms(imo, :, ispin), 1)
2387 at_index = ex_atom_indices(tmp_index)
2388 kind_name = particle_set(at_index)%atomic_kind%name
2390 at_pos = particle_set(at_index)%r
2391 wfn_center = xas_tdp_env%qs_loc_env%localized_wfn_control%centers_set(ispin)%array(1:3, imo)
2392 r_ac =
pbc(at_pos, wfn_center, cell)
2397 mo_spread = xas_tdp_env%qs_loc_env%localized_wfn_control%centers_set(ispin)%array(4, imo)
2400 IF (output_unit > 0)
THEN
2401 WRITE (unit=output_unit, fmt=
"(T3,I4,I10,I14,A14,ES19.3,ES20.3)") &
2402 ispin, imo, at_index, trim(kind_name), dist, mo_spread
2409 IF (output_unit > 0)
THEN
2410 WRITE (unit=output_unit, fmt=
"(T3,A,/)") &
2411 "---------------------------------------------------------------------------------"
2415 cell%perd = perd_init
2417 END SUBROUTINE write_mos_to_ex_atoms_association
2428 SUBROUTINE perform_mulliken_on_donor_state(donor_state, qs_env)
2432 INTEGER :: at_index, i, ispin, nao, natom, ndo_mo, &
2433 ndo_so, nsgf, nspins, output_unit
2434 INTEGER,
DIMENSION(:),
POINTER :: first_sgf, last_sgf
2435 INTEGER,
DIMENSION(:, :),
POINTER :: mo_indices
2436 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: mul_pop, pop_mat
2437 REAL(
dp),
DIMENSION(:, :),
POINTER :: work_array
2445 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2447 NULLIFY (mo_indices, qs_kind_set, particle_set, first_sgf, work_array)
2448 NULLIFY (matrix_s, para_env, blacs_env, col_vect_struct, last_sgf)
2451 at_index = donor_state%at_index
2452 mo_indices => donor_state%mo_indices
2453 ndo_mo = donor_state%ndo_mo
2454 gs_coeffs => donor_state%gs_coeffs
2456 nspins = 1;
IF (
SIZE(mo_indices, 2) == 2) nspins = 2
2457 ndo_so = ndo_mo*nspins
2458 ALLOCATE (mul_pop(ndo_mo, nspins))
2461 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, qs_kind_set=qs_kind_set, &
2462 para_env=para_env, blacs_env=blacs_env, matrix_s=matrix_s)
2463 CALL cp_fm_get_info(gs_coeffs, nrow_global=nao, matrix_struct=col_vect_struct)
2465 natom =
SIZE(particle_set, 1)
2466 ALLOCATE (first_sgf(natom))
2467 ALLOCATE (last_sgf(natom))
2469 CALL get_particle_set(particle_set, qs_kind_set, first_sgf=first_sgf, last_sgf=last_sgf)
2470 nsgf = last_sgf(at_index) - first_sgf(at_index) + 1
2478 ALLOCATE (work_array(nsgf, ndo_so))
2479 ALLOCATE (pop_mat(ndo_so, ndo_so))
2481 CALL cp_fm_get_submatrix(fm=work_vect, target_m=work_array, start_row=first_sgf(at_index), &
2482 start_col=1, n_rows=nsgf, n_cols=ndo_so, transpose=.false.)
2484 CALL dgemm(
'T',
'N', ndo_so, ndo_so, nsgf, 1.0_dp, donor_state%contract_coeffs, nsgf, &
2485 work_array, nsgf, 0.0_dp, pop_mat, ndo_so)
2488 DO ispin = 1, nspins
2490 mul_pop(i, ispin) = pop_mat((ispin - 1)*ndo_mo + i, (ispin - 1)*ndo_mo + i)
2495 IF (output_unit > 0)
THEN
2496 WRITE (unit=output_unit, fmt=
"(T5,A,/,T5,A)") &
2497 "Mulliken population analysis retricted to the associated MO(s) yields: ", &
2498 " Spin MO index charge"
2499 DO ispin = 1, nspins
2501 WRITE (unit=output_unit, fmt=
"(T51,I4,I10,F11.3)") &
2502 ispin, mo_indices(i, ispin), mul_pop(i, ispin)
2508 DEALLOCATE (first_sgf, last_sgf, work_array)
2511 END SUBROUTINE perform_mulliken_on_donor_state
2521 SUBROUTINE xas_tdp_post(ex_type, donor_state, xas_tdp_env, xas_tdp_section, qs_env)
2523 INTEGER,
INTENT(IN) :: ex_type
2529 CHARACTER(len=*),
PARAMETER :: routinen =
'xas_tdp_post'
2531 CHARACTER(len=default_string_length) :: domo, domon, excite, pos, xas_mittle
2532 INTEGER :: ex_state_idx, handle, ic, ido_mo, imo, irep, ispin, n_dependent, n_rep, nao, &
2533 ncubes, ndo_mo, ndo_so, nlumo, nmo, nspins, output_unit
2534 INTEGER,
DIMENSION(:),
POINTER :: bounds,
list, state_list
2535 LOGICAL :: append_cube, do_cubes, do_pdos, &
2537 REAL(
dp),
DIMENSION(:),
POINTER :: lr_evals
2538 REAL(
dp),
DIMENSION(:, :),
POINTER :: centers
2550 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2553 NULLIFY (atomic_kind_set, particle_set, qs_kind_set, mo_set, lr_evals, lr_coeffs)
2554 NULLIFY (mo_struct, para_env, blacs_env, fm_struct, matrix_s, print_key, logger)
2555 NULLIFY (bounds, state_list,
list, mos)
2559 do_pdos = .false.; do_cubes = .false.; do_wfn_restart = .false.
2562 "PRINT%PDOS"),
cp_p_file)) do_pdos = .true.
2565 "PRINT%CUBES"),
cp_p_file)) do_cubes = .true.
2568 "PRINT%RESTART_WFN"),
cp_p_file)) do_wfn_restart = .true.
2570 IF (.NOT. (do_pdos .OR. do_cubes .OR. do_wfn_restart))
RETURN
2572 CALL timeset(routinen, handle)
2575 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, particle_set=particle_set, &
2576 qs_kind_set=qs_kind_set, para_env=para_env, blacs_env=blacs_env, &
2577 matrix_s=matrix_s, mos=mos)
2579 SELECT CASE (ex_type)
2581 lr_evals => donor_state%sc_evals
2582 lr_coeffs => donor_state%sc_coeffs
2586 lr_evals => donor_state%sf_evals
2587 lr_coeffs => donor_state%sf_coeffs
2591 lr_evals => donor_state%sg_evals
2592 lr_coeffs => donor_state%sg_coeffs
2596 lr_evals => donor_state%tp_evals
2597 lr_coeffs => donor_state%tp_coeffs
2602 SELECT CASE (donor_state%state_type)
2611 ndo_mo = donor_state%ndo_mo
2612 ndo_so = ndo_mo*nspins
2613 nmo =
SIZE(lr_evals)
2617 nrow_global=nao, ncol_global=nmo)
2621 IF (do_wfn_restart)
THEN
2624 IF (.NOT. (nspins == 1 .AND. donor_state%state_type ==
xas_1s_type))
THEN
2625 cpabort(
"RESTART.wfn file only available for RKS K-edge XAS spectroscopy")
2628 CALL section_vals_val_get(xas_tdp_section,
"PRINT%RESTART_WFN%EXCITED_STATE_INDEX", n_rep_val=n_rep)
2632 i_rep_val=irep, i_val=ex_state_idx)
2633 cpassert(ex_state_idx <=
SIZE(lr_evals))
2638 IF (
SIZE(mos) == 1) &
2639 restart_mos(ispin)%occupation_numbers = mos(1)%occupation_numbers/2
2642 CALL cp_fm_to_fm_submat(msource=lr_coeffs, mtarget=restart_mos(1)%mo_coeff, nrow=nao, &
2643 ncol=1, s_firstrow=1, s_firstcol=ex_state_idx, t_firstrow=1, &
2644 t_firstcol=donor_state%mo_indices(1, 1))
2646 xas_mittle =
'xasat'//trim(adjustl(
cp_to_string(donor_state%at_index)))//
'_'//trim(domo)// &
2647 '_'//trim(excite)//
'_idx'//trim(adjustl(
cp_to_string(ex_state_idx)))
2649 extension=
".wfn", file_status=
"REPLACE", &
2650 file_action=
"WRITE", file_form=
"UNFORMATTED", &
2651 middle_name=xas_mittle)
2654 qs_kind_set=qs_kind_set, ires=output_unit)
2669 IF (.NOT.
ASSOCIATED(xas_tdp_env%matrix_shalf) .AND. do_pdos)
THEN
2671 nrow_global=nao, ncol_global=nao)
2672 ALLOCATE (xas_tdp_env%matrix_shalf)
2677 CALL cp_fm_power(xas_tdp_env%matrix_shalf, work_fm, 0.5_dp, epsilon(0.0_dp), n_dependent)
2685 IF (output_unit > 0)
THEN
2686 WRITE (unit=output_unit, fmt=
"(/,T5,A,/,T5,A,/,T5,A)") &
2687 "Computing the PDOS of linear-response orbitals for spectral features analysis", &
2688 "Note: using standard PDOS routines => ignore mentions of KS states and MO ", &
2689 " occupation numbers. Eigenvalues in *.pdos files are excitations energies."
2694 IF (nlumo .NE. 0)
THEN
2695 cpwarn(
"NLUMO is irrelevant for XAS_TDP PDOS. It was overwritten to 0.")
2706 ncubes = bounds(2) - bounds(1) + 1
2707 IF (ncubes > 0)
THEN
2708 ALLOCATE (state_list(ncubes))
2710 state_list(ic) = bounds(1) + ic - 1
2714 IF (.NOT.
ASSOCIATED(state_list))
THEN
2721 IF (
ASSOCIATED(
list))
THEN
2723 DO ic = 1,
SIZE(
list)
2724 state_list(ncubes + ic) =
list(ic)
2726 ncubes = ncubes +
SIZE(
list)
2731 IF (.NOT.
ASSOCIATED(state_list))
THEN
2733 ALLOCATE (state_list(1))
2739 IF (append_cube) pos =
"APPEND"
2741 ALLOCATE (centers(6, ncubes))
2747 DO ido_mo = 1, ndo_mo
2748 DO ispin = 1, nspins
2752 CALL allocate_mo_set(mo_set, nao=nao, nmo=nmo, nelectron=nmo, n_el_f=real(nmo,
dp), &
2753 maxocc=1.0_dp, flexible_electron_count=0.0_dp)
2754 CALL init_mo_set(mo_set, fm_ref=mo_coeff, name=
"PDOS XAS_TDP MOs")
2755 mo_set%eigenvalues(:) = lr_evals(:)
2758 IF (nspins == 1 .AND. ndo_mo == 1)
THEN
2763 nrow=nao, ncol=1, s_firstrow=1, &
2764 s_firstcol=(imo - 1)*ndo_so + (ispin - 1)*ndo_mo + ido_mo, &
2765 t_firstrow=1, t_firstcol=imo)
2772 xas_mittle =
'xasat'//trim(adjustl(
cp_to_string(donor_state%at_index)))//
'_'// &
2773 trim(domon)//
'_'//trim(excite)
2777 qs_env, xas_tdp_section, ispin, xas_mittle, &
2778 external_matrix_shalf=xas_tdp_env%matrix_shalf)
2782 CALL qs_print_cubes(qs_env, mo_set%mo_coeff, ncubes, state_list, centers, &
2783 print_key=print_key, root=xas_mittle, ispin=ispin, &
2797 IF (do_cubes)
DEALLOCATE (centers, state_list)
2799 CALL timestop(handle)
2801 END SUBROUTINE xas_tdp_post
2811 SUBROUTINE make_lumo_guess(xas_tdp_env, xas_tdp_control, qs_env)
2813 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2814 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2815 TYPE(qs_environment_type),
POINTER :: qs_env
2817 CHARACTER(len=*),
PARAMETER :: routinen =
'make_lumo_guess'
2819 INTEGER :: handle, ispin, nao, nelec_spin(2), &
2820 nlumo(2), nocc(2), nspins
2822 REAL(dp),
ALLOCATABLE,
DIMENSION(:) :: evals
2823 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
2824 TYPE(cp_fm_struct_type),
POINTER :: fm_struct, lumo_struct
2825 TYPE(cp_fm_type) :: amatrix, bmatrix, evecs, work_fm
2826 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_ks, matrix_s
2827 TYPE(mp_para_env_type),
POINTER :: para_env
2829 NULLIFY (matrix_ks, matrix_s, para_env, blacs_env)
2830 NULLIFY (lumo_struct, fm_struct)
2832 CALL timeset(routinen, handle)
2834 do_os = xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks
2835 nspins = 1;
IF (do_os) nspins = 2
2836 ALLOCATE (xas_tdp_env%lumo_evecs(nspins))
2837 ALLOCATE (xas_tdp_env%lumo_evals(nspins))
2838 CALL get_qs_env(qs_env, matrix_ks=matrix_ks, matrix_s=matrix_s, nelectron_spin=nelec_spin, &
2839 para_env=para_env, blacs_env=blacs_env)
2840 CALL dbcsr_get_info(matrix_s(1)%matrix, nfullrows_total=nao)
2843 nlumo = nao - nelec_spin
2846 nlumo = nao - nelec_spin(1)/2
2847 nocc = nelec_spin(1)/2
2850 ALLOCATE (xas_tdp_env%ot_prec(nspins))
2852 DO ispin = 1, nspins
2855 CALL cp_fm_struct_create(fm_struct, para_env=para_env, context=blacs_env, &
2856 nrow_global=nao, ncol_global=nao)
2857 CALL cp_fm_create(amatrix, fm_struct)
2858 CALL cp_fm_create(bmatrix, fm_struct)
2859 CALL cp_fm_create(evecs, fm_struct)
2860 CALL cp_fm_create(work_fm, fm_struct)
2861 ALLOCATE (evals(nao))
2862 ALLOCATE (xas_tdp_env%lumo_evals(ispin)%array(nlumo(ispin)))
2864 CALL copy_dbcsr_to_fm(matrix_ks(ispin)%matrix, amatrix)
2865 CALL copy_dbcsr_to_fm(matrix_s(1)%matrix, bmatrix)
2868 CALL cp_fm_geeig(amatrix, bmatrix, evecs, evals, work_fm)
2871 CALL cp_fm_struct_create(lumo_struct, para_env=para_env, context=blacs_env, &
2872 nrow_global=nao, ncol_global=nlumo(ispin))
2873 CALL cp_fm_create(xas_tdp_env%lumo_evecs(ispin), lumo_struct)
2875 CALL cp_fm_to_fm_submat(evecs, xas_tdp_env%lumo_evecs(ispin), nrow=nao, &
2876 ncol=nlumo(ispin), s_firstrow=1, s_firstcol=nocc(ispin) + 1, &
2877 t_firstrow=1, t_firstcol=1)
2879 xas_tdp_env%lumo_evals(ispin)%array(1:nlumo(ispin)) = evals(nocc(ispin) + 1:nao)
2881 CALL build_ot_spin_prec(evecs, evals, ispin, xas_tdp_env, xas_tdp_control, qs_env)
2884 CALL cp_fm_release(amatrix)
2885 CALL cp_fm_release(bmatrix)
2886 CALL cp_fm_release(evecs)
2887 CALL cp_fm_release(work_fm)
2888 CALL cp_fm_struct_release(fm_struct)
2889 CALL cp_fm_struct_release(lumo_struct)
2893 CALL timestop(handle)
2895 END SUBROUTINE make_lumo_guess
2908 SUBROUTINE build_ot_spin_prec(evecs, evals, ispin, xas_tdp_env, xas_tdp_control, qs_env)
2910 TYPE(cp_fm_type),
INTENT(IN) :: evecs
2911 REAL(dp),
DIMENSION(:) :: evals
2913 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2914 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2915 TYPE(qs_environment_type),
POINTER :: qs_env
2917 CHARACTER(len=*),
PARAMETER :: routinen =
'build_ot_spin_prec'
2919 INTEGER :: handle, nao, nelec_spin(2), nguess, &
2923 REAL(dp),
ALLOCATABLE,
DIMENSION(:) :: scaling
2924 TYPE(cp_fm_struct_type),
POINTER :: fm_struct
2925 TYPE(cp_fm_type) :: fm_prec, work_fm
2926 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_s
2927 TYPE(mp_para_env_type),
POINTER :: para_env
2929 NULLIFY (fm_struct, para_env, matrix_s)
2931 CALL timeset(routinen, handle)
2933 do_os = xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks
2934 CALL get_qs_env(qs_env, para_env=para_env, nelectron_spin=nelec_spin, matrix_s=matrix_s)
2935 CALL cp_fm_get_info(evecs, nrow_global=nao, matrix_struct=fm_struct)
2936 CALL cp_fm_create(fm_prec, fm_struct)
2937 ALLOCATE (scaling(nao))
2938 nocc = nelec_spin(1)/2
2941 nocc = nelec_spin(ispin)
2947 IF (xas_tdp_control%n_excited > 0 .AND. xas_tdp_control%n_excited < nguess)
THEN
2948 nguess = xas_tdp_control%n_excited/nspins
2949 ELSE IF (xas_tdp_control%e_range > 0.0_dp)
THEN
2950 nguess = count(evals(nocc + 1:nao) - evals(nocc + 1) .LE. xas_tdp_control%e_range)
2954 scaling(nocc + 1:nocc + nguess) = 100.0_dp
2956 shift = evals(nocc + 1) - 0.01_dp
2957 scaling(nocc + nguess:nao) = 1.0_dp/(evals(nocc + nguess:nao) - shift)
2959 scaling(1:nocc) = 1.0_dp
2962 CALL cp_fm_create(work_fm, fm_struct)
2964 CALL cp_fm_copy_general(evecs, work_fm, para_env)
2965 CALL cp_fm_column_scale(work_fm, scaling)
2967 CALL parallel_gemm(
'N',
'T', nao, nao, nao, 1.0_dp, work_fm, evecs, 0.0_dp, fm_prec)
2970 ALLOCATE (xas_tdp_env%ot_prec(ispin)%matrix)
2971 CALL dbcsr_create(xas_tdp_env%ot_prec(ispin)%matrix, template=matrix_s(1)%matrix, name=
"OT_PREC")
2972 CALL copy_fm_to_dbcsr(fm_prec, xas_tdp_env%ot_prec(ispin)%matrix)
2973 CALL dbcsr_filter(xas_tdp_env%ot_prec(ispin)%matrix, xas_tdp_control%eps_filter)
2975 CALL cp_fm_release(work_fm)
2976 CALL cp_fm_release(fm_prec)
2978 CALL timestop(handle)
2980 END SUBROUTINE build_ot_spin_prec
2989 SUBROUTINE print_xps(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
2991 TYPE(donor_state_type),
POINTER :: donor_state
2992 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2993 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2994 TYPE(qs_environment_type),
POINTER :: qs_env
2996 INTEGER :: ido_mo, ispin, nspins, output_unit
2997 REAL(dp),
ALLOCATABLE,
DIMENSION(:, :) :: ips, soc_shifts
2999 output_unit = cp_logger_get_default_io_unit()
3001 nspins = 1;
IF (xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks) nspins = 2
3003 ALLOCATE (ips(
SIZE(donor_state%gw2x_evals, 1),
SIZE(donor_state%gw2x_evals, 2)))
3004 ips(:, :) = donor_state%gw2x_evals(:, :)
3007 IF (.NOT. xas_tdp_control%is_periodic)
THEN
3010 IF (donor_state%ndo_mo > 1)
THEN
3011 CALL get_soc_splitting(soc_shifts, donor_state, xas_tdp_env, xas_tdp_control, qs_env)
3012 ips(:, :) = ips(:, :) + soc_shifts
3014 IF (output_unit > 0)
THEN
3015 WRITE (output_unit, fmt=
"(/,T5,A,F23.6)") &
3016 "Ionization potentials for XPS (GW2X + SOC): ", -ips(1, 1)*evolt
3018 DO ispin = 1, nspins
3019 DO ido_mo = 1, donor_state%ndo_mo
3021 IF (ispin == 1 .AND. ido_mo == 1) cycle
3023 WRITE (output_unit, fmt=
"(T5,A,F23.6)") &
3024 " ", -ips(ido_mo, ispin)*evolt
3033 IF (output_unit > 0)
THEN
3034 WRITE (output_unit, fmt=
"(/,T5,A,F29.6)") &
3035 "Ionization potentials for XPS (GW2X): ", -ips(1, 1)*evolt
3037 IF (nspins == 2)
THEN
3038 WRITE (output_unit, fmt=
"(T5,A,F29.6)") &
3039 " ", -ips(1, 2)*evolt
3046 END SUBROUTINE print_xps
3055 SUBROUTINE print_xas_tdp_to_file(donor_state, xas_tdp_env, xas_tdp_control, xas_tdp_section)
3057 TYPE(donor_state_type),
POINTER :: donor_state
3058 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
3059 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
3060 TYPE(section_vals_type),
POINTER :: xas_tdp_section
3062 INTEGER :: i, output_unit, xas_tdp_unit
3063 TYPE(cp_logger_type),
POINTER :: logger
3066 logger => cp_get_default_logger()
3068 xas_tdp_unit = cp_print_key_unit_nr(logger, xas_tdp_section,
"PRINT%SPECTRUM", &
3069 extension=
".spectrum", file_position=
"APPEND", &
3070 file_action=
"WRITE", file_form=
"FORMATTED")
3072 output_unit = cp_logger_get_default_io_unit()
3074 IF (output_unit > 0)
THEN
3075 WRITE (output_unit, fmt=
"(/,T5,A,/)") &
3076 "Calculations done: "
3079 IF (xas_tdp_control%do_spin_cons)
THEN
3080 IF (xas_tdp_unit > 0)
THEN
3083 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3084 "==================================================================================", &
3085 "XAS TDP open-shell spin-conserving (no SOC) excitations for DONOR STATE: ", &
3086 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3087 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3088 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3089 "=================================================================================="
3093 IF (xas_tdp_control%do_quad)
THEN
3094 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3095 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3096 DO i = 1,
SIZE(donor_state%sc_evals)
3097 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3098 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4), &
3099 donor_state%quad_osc_str(i)
3101 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3102 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3103 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3104 DO i = 1,
SIZE(donor_state%sc_evals)
3105 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3106 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4), &
3107 donor_state%osc_str(i, 1), donor_state%osc_str(i, 2), donor_state%osc_str(i, 3)
3109 ELSE IF (xas_tdp_control%spin_dip)
THEN
3110 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3111 " Index Excitation energy (eV) fosc dipole (a.u.) alpha-comp beta-comp"
3112 DO i = 1,
SIZE(donor_state%sc_evals)
3113 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6)") &
3114 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4), &
3115 donor_state%alpha_osc(i, 4), donor_state%beta_osc(i, 4)
3118 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3119 " Index Excitation energy (eV) fosc dipole (a.u.)"
3120 DO i = 1,
SIZE(donor_state%sc_evals)
3121 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3122 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4)
3126 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3129 IF (output_unit > 0)
THEN
3130 WRITE (output_unit, fmt=
"(T5,A,F17.6)") &
3131 "First spin-conserving XAS excitation energy (eV): ", donor_state%sc_evals(1)*evolt
3136 IF (xas_tdp_control%do_spin_flip)
THEN
3137 IF (xas_tdp_unit > 0)
THEN
3140 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3141 "==================================================================================", &
3142 "XAS TDP open-shell spin-flip (no SOC) excitations for DONOR STATE: ", &
3143 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3144 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3145 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3146 "=================================================================================="
3150 IF (xas_tdp_control%do_quad)
THEN
3151 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3152 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3153 DO i = 1,
SIZE(donor_state%sf_evals)
3154 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3155 i, donor_state%sf_evals(i)*evolt, 0.0_dp, 0.0_dp
3157 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3158 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3159 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3160 DO i = 1,
SIZE(donor_state%sf_evals)
3161 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3162 i, donor_state%sf_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp
3164 ELSE IF (xas_tdp_control%spin_dip)
THEN
3165 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3166 " Index Excitation energy (eV) fosc dipole (a.u.) alpha-comp beta-comp"
3167 DO i = 1,
SIZE(donor_state%sf_evals)
3168 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6)") &
3169 i, donor_state%sf_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp
3172 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3173 " Index Excitation energy (eV) fosc dipole (a.u.)"
3174 DO i = 1,
SIZE(donor_state%sf_evals)
3175 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3176 i, donor_state%sf_evals(i)*evolt, 0.0_dp
3180 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3183 IF (output_unit > 0)
THEN
3184 WRITE (output_unit, fmt=
"(T5,A,F23.6)") &
3185 "First spin-flip XAS excitation energy (eV): ", donor_state%sf_evals(1)*evolt
3189 IF (xas_tdp_control%do_singlet)
THEN
3190 IF (xas_tdp_unit > 0)
THEN
3193 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3194 "==================================================================================", &
3195 "XAS TDP singlet excitations (no SOC) for DONOR STATE: ", &
3196 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3197 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3198 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3199 "=================================================================================="
3203 IF (xas_tdp_control%do_quad)
THEN
3204 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3205 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3206 DO i = 1,
SIZE(donor_state%sg_evals)
3207 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3208 i, donor_state%sg_evals(i)*evolt, donor_state%osc_str(i, 4), &
3209 donor_state%quad_osc_str(i)
3211 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3212 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3213 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3214 DO i = 1,
SIZE(donor_state%sg_evals)
3215 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3216 i, donor_state%sg_evals(i)*evolt, donor_state%osc_str(i, 4), &
3217 donor_state%osc_str(i, 1), donor_state%osc_str(i, 2), donor_state%osc_str(i, 3)
3220 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3221 " Index Excitation energy (eV) fosc dipole (a.u.)"
3222 DO i = 1,
SIZE(donor_state%sg_evals)
3223 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3224 i, donor_state%sg_evals(i)*evolt, donor_state%osc_str(i, 4)
3228 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3231 IF (output_unit > 0)
THEN
3232 WRITE (output_unit, fmt=
"(T5,A,F25.6)") &
3233 "First singlet XAS excitation energy (eV): ", donor_state%sg_evals(1)*evolt
3237 IF (xas_tdp_control%do_triplet)
THEN
3238 IF (xas_tdp_unit > 0)
THEN
3241 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3242 "==================================================================================", &
3243 "XAS TDP triplet excitations (no SOC) for DONOR STATE: ", &
3244 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3245 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3246 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3247 "=================================================================================="
3251 IF (xas_tdp_control%do_quad)
THEN
3252 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3253 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3254 DO i = 1,
SIZE(donor_state%tp_evals)
3255 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3256 i, donor_state%tp_evals(i)*evolt, 0.0_dp, 0.0_dp
3258 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3259 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3260 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3261 DO i = 1,
SIZE(donor_state%tp_evals)
3262 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3263 i, donor_state%tp_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp
3265 ELSE IF (xas_tdp_control%spin_dip)
THEN
3266 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3267 " Index Excitation energy (eV) fosc dipole (a.u.) alpha-comp beta-comp"
3268 DO i = 1,
SIZE(donor_state%tp_evals)
3269 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6)") &
3270 i, donor_state%tp_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp
3273 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3274 " Index Excitation energy (eV) fosc dipole (a.u.)"
3275 DO i = 1,
SIZE(donor_state%tp_evals)
3276 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3277 i, donor_state%tp_evals(i)*evolt, 0.0_dp
3281 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3284 IF (output_unit > 0)
THEN
3285 WRITE (output_unit, fmt=
"(T5,A,F25.6)") &
3286 "First triplet XAS excitation energy (eV): ", donor_state%tp_evals(1)*evolt
3290 IF (xas_tdp_control%do_soc .AND. donor_state%state_type == xas_2p_type)
THEN
3291 IF (xas_tdp_unit > 0)
THEN
3294 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3295 "==================================================================================", &
3296 "XAS TDP excitations after spin-orbit coupling for DONOR STATE: ", &
3297 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3298 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3299 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3300 "=================================================================================="
3303 IF (xas_tdp_control%do_quad)
THEN
3304 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3305 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3306 DO i = 1,
SIZE(donor_state%soc_evals)
3307 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3308 i, donor_state%soc_evals(i)*evolt, donor_state%soc_osc_str(i, 4), &
3309 donor_state%soc_quad_osc_str(i)
3311 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3312 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3313 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3314 DO i = 1,
SIZE(donor_state%soc_evals)
3315 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3316 i, donor_state%soc_evals(i)*evolt, donor_state%soc_osc_str(i, 4), &
3317 donor_state%soc_osc_str(i, 1), donor_state%soc_osc_str(i, 2), donor_state%soc_osc_str(i, 3)
3320 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3321 " Index Excitation energy (eV) fosc dipole (a.u.)"
3322 DO i = 1,
SIZE(donor_state%soc_evals)
3323 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3324 i, donor_state%soc_evals(i)*evolt, donor_state%soc_osc_str(i, 4)
3328 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3331 IF (output_unit > 0)
THEN
3332 WRITE (output_unit, fmt=
"(T5,A,F29.6)") &
3333 "First SOC XAS excitation energy (eV): ", donor_state%soc_evals(1)*evolt
3337 CALL cp_print_key_finished_output(xas_tdp_unit, logger, xas_tdp_section,
"PRINT%SPECTRUM")
3339 END SUBROUTINE print_xas_tdp_to_file
3349 SUBROUTINE write_donor_state_restart(ex_type, donor_state, xas_tdp_section, qs_env)
3351 INTEGER,
INTENT(IN) :: ex_type
3352 TYPE(donor_state_type),
POINTER :: donor_state
3353 TYPE(section_vals_type),
POINTER :: xas_tdp_section
3354 TYPE(qs_environment_type),
POINTER :: qs_env
3356 CHARACTER(len=*),
PARAMETER :: routinen =
'write_donor_state_restart'
3358 CHARACTER(len=default_path_length) :: filename
3359 CHARACTER(len=default_string_length) :: domo, excite, my_middle
3360 INTEGER :: ex_atom, handle, ispin, nao, ndo_mo, &
3361 nex, nspins, output_unit, rst_unit, &
3363 INTEGER,
DIMENSION(:, :),
POINTER :: mo_indices
3365 REAL(dp),
DIMENSION(:),
POINTER :: lr_evals
3366 TYPE(cp_fm_type),
POINTER :: lr_coeffs
3367 TYPE(cp_logger_type),
POINTER :: logger
3368 TYPE(mo_set_type),
DIMENSION(:),
POINTER :: mos
3369 TYPE(section_vals_type),
POINTER :: print_key
3371 NULLIFY (logger, lr_coeffs, lr_evals, print_key, mos)
3374 logger => cp_get_default_logger()
3376 IF (btest(cp_print_key_should_output(logger%iter_info, xas_tdp_section, &
3377 "PRINT%RESTART", used_print_key=print_key), cp_p_file)) do_print = .true.
3379 IF (.NOT. do_print)
RETURN
3381 CALL timeset(routinen, handle)
3383 output_unit = cp_logger_get_default_io_unit()
3386 SELECT CASE (ex_type)
3387 CASE (tddfpt_spin_cons)
3388 lr_evals => donor_state%sc_evals
3389 lr_coeffs => donor_state%sc_coeffs
3392 CASE (tddfpt_spin_flip)
3393 lr_evals => donor_state%sf_evals
3394 lr_coeffs => donor_state%sf_coeffs
3397 CASE (tddfpt_singlet)
3398 lr_evals => donor_state%sg_evals
3399 lr_coeffs => donor_state%sg_coeffs
3402 CASE (tddfpt_triplet)
3403 lr_evals => donor_state%tp_evals
3404 lr_coeffs => donor_state%tp_coeffs
3409 SELECT CASE (donor_state%state_type)
3418 ndo_mo = donor_state%ndo_mo
3419 nex =
SIZE(lr_evals)
3420 CALL cp_fm_get_info(lr_coeffs, nrow_global=nao)
3421 state_type = donor_state%state_type
3422 ex_atom = donor_state%at_index
3423 mo_indices => donor_state%mo_indices
3427 my_middle =
'xasat'//trim(adjustl(cp_to_string(ex_atom)))//
'_'//trim(domo)//
'_'//trim(excite)
3428 rst_unit = cp_print_key_unit_nr(logger, xas_tdp_section,
"PRINT%RESTART", extension=
".rst", &
3429 file_status=
"REPLACE", file_action=
"WRITE", &
3430 file_form=
"UNFORMATTED", middle_name=trim(my_middle))
3432 filename = cp_print_key_generate_filename(logger, print_key, middle_name=trim(my_middle), &
3433 extension=
".rst", my_local=.false.)
3435 IF (output_unit > 0)
THEN
3436 WRITE (unit=output_unit, fmt=
"(/,T5,A,/T5,A,A,A)") &
3437 "Linear-response orbitals and excitation energies are written in: ", &
3438 '"', trim(filename),
'"'
3442 IF (rst_unit > 0)
THEN
3443 WRITE (rst_unit) ex_atom, state_type, ndo_mo, ex_type
3444 WRITE (rst_unit) nao, nex, nspins
3445 WRITE (rst_unit) mo_indices(:, :)
3446 WRITE (rst_unit) lr_evals(:)
3448 CALL cp_fm_write_unformatted(lr_coeffs, rst_unit)
3451 CALL get_qs_env(qs_env, mos=mos)
3452 DO ispin = 1, nspins
3453 CALL cp_fm_write_unformatted(mos(ispin)%mo_coeff, rst_unit)
3457 CALL cp_print_key_finished_output(rst_unit, logger, xas_tdp_section,
"PRINT%RESTART")
3459 CALL timestop(handle)
3461 END SUBROUTINE write_donor_state_restart
3470 SUBROUTINE read_donor_state_restart(donor_state, ex_type, filename, qs_env)
3472 TYPE(donor_state_type),
POINTER :: donor_state
3473 INTEGER,
INTENT(OUT) :: ex_type
3474 CHARACTER(len=*),
INTENT(IN) :: filename
3475 TYPE(qs_environment_type),
POINTER :: qs_env
3477 CHARACTER(len=*),
PARAMETER :: routinen =
'read_donor_state_restart'
3479 INTEGER :: handle, ispin, nao, nex, nspins, &
3480 output_unit, read_params(7), rst_unit
3481 INTEGER,
DIMENSION(:, :),
POINTER :: mo_indices
3482 LOGICAL :: file_exists
3483 REAL(dp),
DIMENSION(:),
POINTER :: lr_evals
3484 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
3485 TYPE(cp_fm_struct_type),
POINTER :: fm_struct
3486 TYPE(cp_fm_type),
POINTER :: lr_coeffs
3487 TYPE(mo_set_type),
DIMENSION(:),
POINTER :: mos
3488 TYPE(mp_comm_type) :: group
3489 TYPE(mp_para_env_type),
POINTER :: para_env
3491 NULLIFY (lr_evals, lr_coeffs, para_env, fm_struct, blacs_env, mos)
3493 CALL timeset(routinen, handle)
3495 output_unit = cp_logger_get_default_io_unit()
3496 cpassert(
ASSOCIATED(donor_state))
3497 CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
3500 file_exists = .false.
3503 IF (para_env%is_source())
THEN
3505 INQUIRE (file=filename, exist=file_exists)
3506 IF (.NOT. file_exists) cpabort(
"Trying to read non-existing XAS_TDP restart file")
3508 CALL open_file(file_name=trim(filename), file_action=
"READ", file_form=
"UNFORMATTED", &
3509 file_position=
"REWIND", file_status=
"OLD", unit_number=rst_unit)
3512 IF (output_unit > 0)
THEN
3513 WRITE (unit=output_unit, fmt=
"(/,T5,A,/,T5,A,A,A)") &
3514 "Reading linear-response orbitals and excitation energies from file: ", &
3519 IF (rst_unit > 0)
THEN
3520 READ (rst_unit) read_params(1:4)
3521 READ (rst_unit) read_params(5:7)
3523 CALL group%bcast(read_params)
3524 donor_state%at_index = read_params(1)
3525 donor_state%state_type = read_params(2)
3526 donor_state%ndo_mo = read_params(3)
3527 ex_type = read_params(4)
3528 nao = read_params(5)
3529 nex = read_params(6)
3530 nspins = read_params(7)
3532 ALLOCATE (mo_indices(donor_state%ndo_mo, nspins))
3533 IF (rst_unit > 0)
THEN
3534 READ (rst_unit) mo_indices(1:donor_state%ndo_mo, 1:nspins)
3536 CALL group%bcast(mo_indices)
3537 donor_state%mo_indices => mo_indices
3540 ALLOCATE (lr_evals(nex))
3541 IF (rst_unit > 0)
READ (rst_unit) lr_evals(1:nex)
3542 CALL group%bcast(lr_evals)
3545 CALL cp_fm_struct_create(fm_struct, context=blacs_env, para_env=para_env, &
3546 nrow_global=nao, ncol_global=nex*donor_state%ndo_mo*nspins)
3547 ALLOCATE (lr_coeffs)
3548 CALL cp_fm_create(lr_coeffs, fm_struct)
3549 CALL cp_fm_read_unformatted(lr_coeffs, rst_unit)
3550 CALL cp_fm_struct_release(fm_struct)
3553 CALL get_qs_env(qs_env, mos=mos)
3554 DO ispin = 1, nspins
3555 CALL cp_fm_read_unformatted(mos(ispin)%mo_coeff, rst_unit)
3559 IF (para_env%is_source())
THEN
3560 CALL close_file(unit_number=rst_unit)
3564 SELECT CASE (ex_type)
3565 CASE (tddfpt_spin_cons)
3566 donor_state%sc_evals => lr_evals
3567 donor_state%sc_coeffs => lr_coeffs
3568 CASE (tddfpt_spin_flip)
3569 donor_state%sf_evals => lr_evals
3570 donor_state%sf_coeffs => lr_coeffs
3571 CASE (tddfpt_singlet)
3572 donor_state%sg_evals => lr_evals
3573 donor_state%sg_coeffs => lr_coeffs
3574 CASE (tddfpt_triplet)
3575 donor_state%tp_evals => lr_evals
3576 donor_state%tp_coeffs => lr_coeffs
3579 CALL timestop(handle)
3581 END SUBROUTINE read_donor_state_restart
3589 SUBROUTINE restart_calculation(rst_filename, xas_tdp_section, qs_env)
3591 CHARACTER(len=*),
INTENT(IN) :: rst_filename
3592 TYPE(section_vals_type),
POINTER :: xas_tdp_section
3593 TYPE(qs_environment_type),
POINTER :: qs_env
3596 TYPE(donor_state_type),
POINTER :: donor_state
3597 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
3599 NULLIFY (xas_tdp_env, donor_state)
3602 ALLOCATE (donor_state)
3603 CALL donor_state_create(donor_state)
3604 CALL read_donor_state_restart(donor_state, ex_type, rst_filename, qs_env)
3607 CALL xas_tdp_env_create(xas_tdp_env)
3608 CALL xas_tdp_post(ex_type, donor_state, xas_tdp_env, xas_tdp_section, qs_env)
3611 CALL xas_tdp_env_release(xas_tdp_env)
3612 CALL free_ds_memory(donor_state)
3613 DEALLOCATE (donor_state%mo_indices)
3614 DEALLOCATE (donor_state)
3616 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, 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, ecoul_1c, rho0_s_rs, rho0_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, 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, 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.