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
604 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, mo_evals, cell)
611 NULLIFY (mo_coeff, matrix_ks, admm_env, dummy_section, matrix_p)
614 CALL get_qs_env(qs_env, dft_control=dft_control, do_rixs=do_rixs)
626 IF (dft_control%uks) xas_tdp_control%do_uks = .true.
627 IF (dft_control%roks) xas_tdp_control%do_roks = .true.
628 do_uks = xas_tdp_control%do_uks
629 do_os = do_uks .OR. xas_tdp_control%do_roks
632 IF (
PRESENT(rixs_env))
THEN
633 xas_tdp_env => rixs_env%core_state
642 nex_atoms =
SIZE(xas_tdp_control%list_ex_atoms)
644 ALLOCATE (xas_tdp_env%ex_atom_indices(nex_atoms))
645 ALLOCATE (xas_tdp_env%state_types(
SIZE(xas_tdp_control%state_types, 1), nex_atoms))
646 xas_tdp_env%ex_atom_indices = xas_tdp_control%list_ex_atoms
647 xas_tdp_env%state_types = xas_tdp_control%state_types
651 IF (any(xas_tdp_env%ex_atom_indices > natom))
THEN
652 cpabort(
"Invalid index for the ATOM_LIST keyword.")
656 ALLOCATE (xas_tdp_env%ex_kind_indices(nex_atoms))
657 xas_tdp_env%ex_kind_indices = 0
659 CALL get_qs_env(qs_env, particle_set=particle_set)
661 at_ind = xas_tdp_env%ex_atom_indices(i)
663 IF (all(abs(xas_tdp_env%ex_kind_indices - j) /= 0))
THEN
665 xas_tdp_env%ex_kind_indices(k) = j
670 CALL reallocate(xas_tdp_env%ex_kind_indices, 1, nex_kinds)
675 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=at_kind_set)
676 n_kinds =
SIZE(at_kind_set)
679 nex_kinds =
SIZE(xas_tdp_control%list_ex_kinds)
680 ALLOCATE (xas_tdp_env%ex_kind_indices(nex_kinds))
685 natom=nat_of_kind, kind_number=kind_ind)
686 IF (any(xas_tdp_control%list_ex_kinds == kind_name))
THEN
687 nex_atoms = nex_atoms + nat_of_kind
689 xas_tdp_env%ex_kind_indices(k) = kind_ind
693 ALLOCATE (xas_tdp_env%ex_atom_indices(nex_atoms))
694 ALLOCATE (xas_tdp_env%state_types(
SIZE(xas_tdp_control%state_types, 1), nex_atoms))
700 natom=nat_of_kind, atom_list=ind_of_kind)
702 IF (xas_tdp_control%list_ex_kinds(j) == kind_name)
THEN
703 xas_tdp_env%ex_atom_indices(nex_atoms + 1:nex_atoms + nat_of_kind) = ind_of_kind
704 DO k = 1,
SIZE(xas_tdp_control%state_types, 1)
705 xas_tdp_env%state_types(k, nex_atoms + 1:nex_atoms + nat_of_kind) = &
706 xas_tdp_control%state_types(k, j)
708 nex_atoms = nex_atoms + nat_of_kind
714 CALL set_xas_tdp_env(xas_tdp_env, nex_atoms=nex_atoms, nex_kinds=nex_kinds)
717 IF (nmatch /=
SIZE(xas_tdp_control%list_ex_kinds))
THEN
718 cpabort(
"Invalid kind(s) for the KIND_LIST keyword.")
724 CALL sort_unique(xas_tdp_env%ex_atom_indices, unique)
725 IF (.NOT. unique)
THEN
726 cpabort(
"Excited atoms not uniquely defined.")
731 IF (all(cell%perd == 0))
THEN
732 xas_tdp_control%is_periodic = .false.
733 ELSE IF (all(cell%perd == 1))
THEN
734 xas_tdp_control%is_periodic = .true.
736 cpabort(
"XAS TDP only implemented for full PBCs or non-PBCs")
741 ALLOCATE (xas_tdp_env%donor_states(n_donor_states))
742 DO i = 1, n_donor_states
747 IF (dft_control%do_admm)
THEN
748 CALL get_qs_env(qs_env, admm_env=admm_env, matrix_ks=matrix_ks)
750 DO ispin = 1, dft_control%nspins
756 IF (xas_tdp_control%eps_pgf > 0.0_dp)
THEN
757 CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set)
759 DO i = 1,
SIZE(qs_kind_set)
760 CALL get_qs_kind(qs_kind_set(i), basis_set=tmp_basis, basis_type=
"ORB")
762 CALL get_qs_kind(qs_kind_set(i), basis_set=tmp_basis, basis_type=
"RI_XAS")
770 CALL get_qs_env(qs_env, mos=mos, matrix_ks=matrix_ks)
771 nspins = 1;
IF (do_uks) nspins = 2
774 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, eigenvalues=mo_evals)
784 l_val=xas_tdp_control%do_loc)
787 xas_tdp_control%loc_subsection,
"PRINT")
789 ALLOCATE (xas_tdp_env%qs_loc_env)
791 qs_loc_env => xas_tdp_env%qs_loc_env
792 loc_section => xas_tdp_control%loc_subsection
795 CALL get_mo_set(mos(1), nmo=n_mo(1), homo=homo(1), nao=nao)
799 IF (do_os)
CALL get_mo_set(mos(2), nmo=n_mo(2), homo=homo(2))
800 IF (do_uks) nspins = 2
803 IF (xas_tdp_control%n_search < 0 .OR. xas_tdp_control%n_search > minval(homo)) &
804 xas_tdp_control%n_search = minval(homo)
806 nloc_xas=xas_tdp_control%n_search, spin_xas=1)
810 qs_loc_env%localized_wfn_control%nloc_states(2) = xas_tdp_control%n_search
811 qs_loc_env%localized_wfn_control%lu_bound_states(1, 2) = 1
812 qs_loc_env%localized_wfn_control%lu_bound_states(2, 2) = xas_tdp_control%n_search
816 qs_loc_env%localized_wfn_control%operator_type =
op_loc_berry
817 qs_loc_env%localized_wfn_control%max_iter = 25000
818 IF (.NOT. xas_tdp_control%do_loc)
THEN
819 qs_loc_env%localized_wfn_control%localization_method =
do_loc_none
821 n_moloc = qs_loc_env%localized_wfn_control%nloc_states
822 CALL set_loc_centers(qs_loc_env%localized_wfn_control, n_moloc, nspins)
825 qs_env, do_localize=.true.)
828 qs_env, do_localize=.true., myspin=1)
834 ALLOCATE (xas_tdp_env%mos_of_ex_atoms(xas_tdp_control%n_search, nex_atoms, nspins))
837 IF (do_os) nspins = 2
838 CALL get_qs_env(qs_env, matrix_s=matrix_s, mos=mos)
840 ALLOCATE (xas_tdp_env%q_projector(nspins))
841 ALLOCATE (xas_tdp_env%q_projector(1)%matrix)
842 CALL dbcsr_create(xas_tdp_env%q_projector(1)%matrix, name=
"Q PROJECTOR ALPHA", &
843 template=matrix_s(1)%matrix, matrix_type=dbcsr_type_no_symmetry)
845 ALLOCATE (xas_tdp_env%q_projector(2)%matrix)
846 CALL dbcsr_create(xas_tdp_env%q_projector(2)%matrix, name=
"Q PROJECTOR BETA", &
847 template=matrix_s(1)%matrix, matrix_type=dbcsr_type_no_symmetry)
851 CALL dbcsr_create(matrix_p, name=
"RHO_AO", template=matrix_s(1)%matrix, matrix_type=dbcsr_type_no_symmetry)
855 fact = -0.5_dp;
IF (do_os) fact = -1.0_dp
859 CALL dbcsr_multiply(
'N',
'N', fact, matrix_s(1)%matrix, matrix_p, 0.0_dp, &
860 xas_tdp_env%q_projector(1)%matrix, filter_eps=xas_tdp_control%eps_filter)
867 CALL dbcsr_multiply(
'N',
'N', fact, matrix_s(1)%matrix, matrix_p, 0.0_dp, &
868 xas_tdp_env%q_projector(2)%matrix, filter_eps=xas_tdp_control%eps_filter)
874 DEALLOCATE (matrix_p)
877 ALLOCATE (xas_tdp_env%dipmat(3))
879 ALLOCATE (xas_tdp_env%dipmat(i)%matrix)
880 CALL dbcsr_copy(matrix_tmp, matrix_s(1)%matrix, name=
"XAS TDP dipole matrix")
881 IF (xas_tdp_control%dipole_form ==
xas_dip_vel)
THEN
882 CALL dbcsr_create(xas_tdp_env%dipmat(i)%matrix, template=matrix_s(1)%matrix, &
883 matrix_type=dbcsr_type_antisymmetric)
886 CALL dbcsr_create(xas_tdp_env%dipmat(i)%matrix, template=matrix_s(1)%matrix, &
887 matrix_type=dbcsr_type_symmetric)
888 CALL dbcsr_copy(xas_tdp_env%dipmat(i)%matrix, matrix_tmp)
890 CALL dbcsr_set(xas_tdp_env%dipmat(i)%matrix, 0.0_dp)
895 IF (xas_tdp_control%do_quad)
THEN
896 ALLOCATE (xas_tdp_env%quadmat(6))
898 ALLOCATE (xas_tdp_env%quadmat(i)%matrix)
899 CALL dbcsr_copy(xas_tdp_env%quadmat(i)%matrix, matrix_s(1)%matrix, name=
"XAS TDP quadrupole matrix")
900 CALL dbcsr_set(xas_tdp_env%quadmat(i)%matrix, 0.0_dp)
905 IF (xas_tdp_control%dipole_form ==
xas_dip_vel)
THEN
907 CALL p_xyz_ao(xas_tdp_env%dipmat, qs_env, minimum_image=.true.)
911 IF (xas_tdp_control%do_soc .OR. xas_tdp_control%do_gw2x)
THEN
912 ALLOCATE (xas_tdp_env%orb_soc(3))
914 ALLOCATE (xas_tdp_env%orb_soc(i)%matrix)
919 CALL safety_check(xas_tdp_control, qs_env)
925 IF (xas_tdp_control%do_ot .OR. xas_tdp_control%do_gw2x)
THEN
926 CALL make_lumo_guess(xas_tdp_env, xas_tdp_control, qs_env)
939 SUBROUTINE get_ri_3c_batches(ex_atoms_of_kind, nbatch, batch_size, atoms_of_kind, xas_tdp_env)
941 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(INOUT) :: ex_atoms_of_kind
942 INTEGER,
INTENT(OUT) :: nbatch
943 INTEGER,
INTENT(IN) :: batch_size
944 INTEGER,
DIMENSION(:),
INTENT(IN) :: atoms_of_kind
947 INTEGER :: iat, iatom, nex_atom
952 DO iat = 1,
SIZE(atoms_of_kind)
953 iatom = atoms_of_kind(iat)
954 IF (.NOT. any(xas_tdp_env%ex_atom_indices == iatom)) cycle
955 nex_atom = nex_atom + 1
958 ALLOCATE (ex_atoms_of_kind(nex_atom))
960 DO iat = 1,
SIZE(atoms_of_kind)
961 iatom = atoms_of_kind(iat)
962 IF (.NOT. any(xas_tdp_env%ex_atom_indices == iatom)) cycle
963 nex_atom = nex_atom + 1
964 ex_atoms_of_kind(nex_atom) = iatom
969 CALL rng_stream%shuffle(ex_atoms_of_kind(1:nex_atom))
971 nbatch = nex_atom/batch_size
972 IF (nbatch*batch_size /= nex_atom) nbatch = nbatch + 1
974 END SUBROUTINE get_ri_3c_batches
981 SUBROUTINE safety_check(xas_tdp_control, qs_env)
989 IF (xas_tdp_control%is_periodic .AND. xas_tdp_control%do_hfx &
991 cpabort(
"XAS TDP with Coulomb operator for exact exchange only supports non-periodic BCs")
995 IF (xas_tdp_control%do_roks .OR. xas_tdp_control%do_uks)
THEN
997 IF (.NOT. (xas_tdp_control%do_spin_cons .OR. xas_tdp_control%do_spin_flip))
THEN
998 cpabort(
"Need spin-conserving and/or spin-flip excitations for open-shell systems")
1001 IF (xas_tdp_control%do_singlet .OR. xas_tdp_control%do_triplet)
THEN
1002 cpabort(
"Singlet/triplet excitations only for restricted closed-shell systems")
1005 IF (xas_tdp_control%do_soc .AND. .NOT. &
1006 (xas_tdp_control%do_spin_flip .AND. xas_tdp_control%do_spin_cons))
THEN
1008 cpabort(
"Both spin-conserving and spin-flip excitations are required for SOC")
1012 IF (.NOT. (xas_tdp_control%do_singlet .OR. xas_tdp_control%do_triplet))
THEN
1013 cpabort(
"Need singlet and/or triplet excitations for closed-shell systems")
1016 IF (xas_tdp_control%do_spin_cons .OR. xas_tdp_control%do_spin_flip)
THEN
1017 cpabort(
"Spin-conserving/spin-flip excitations only for open-shell systems")
1020 IF (xas_tdp_control%do_soc .AND. .NOT. &
1021 (xas_tdp_control%do_singlet .AND. xas_tdp_control%do_triplet))
THEN
1023 cpabort(
"Both singlet and triplet excitations are needed for SOC")
1028 IF (xas_tdp_control%do_soc .AND. xas_tdp_control%e_range > 0.0_dp)
THEN
1029 cpwarn(
"Using E_RANGE and SOC together may lead to crashes, use N_EXCITED for safety.")
1033 IF (.NOT. xas_tdp_control%tamm_dancoff)
THEN
1035 IF (xas_tdp_control%do_spin_flip)
THEN
1036 cpabort(
"Spin-flip kernel only implemented for Tamm-Dancoff approximation")
1039 IF (xas_tdp_control%do_ot)
THEN
1040 cpabort(
"OT diagonalization only available within the Tamm-Dancoff approximation")
1045 IF (xas_tdp_control%do_gw2x)
THEN
1046 IF (.NOT. xas_tdp_control%do_hfx)
THEN
1047 cpabort(
"GW2x requires the definition of the EXACT_EXCHANGE kernel")
1049 IF (.NOT. xas_tdp_control%do_loc)
THEN
1050 cpabort(
"GW2X requires the LOCALIZE keyword in DONOR_STATES")
1055 CALL get_qs_env(qs_env, dft_control=dft_control)
1056 IF (dft_control%do_admm)
THEN
1061 cpabort(
"XAS_TDP only compatible with ADMM purification NONE, CAUCHY_SUBSPACE and MO_DIAG")
1066 END SUBROUTINE safety_check
1074 SUBROUTINE print_info(ou, xas_tdp_control, qs_env)
1076 INTEGER,
INTENT(IN) :: ou
1086 NULLIFY (input, kernel_section, dft_control, matrix_s)
1088 CALL get_qs_env(qs_env, input=input, dft_control=dft_control, matrix_s=matrix_s)
1096 IF (xas_tdp_control%do_uks)
THEN
1097 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1098 "XAS_TDP| Reference calculation: Unrestricted Kohn-Sham"
1099 ELSE IF (xas_tdp_control%do_roks)
THEN
1100 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1101 "XAS_TDP| Reference calculation: Restricted Open-Shell Kohn-Sham"
1103 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1104 "XAS_TDP| Reference calculation: Restricted Closed-Shell Kohn-Sham"
1108 IF (xas_tdp_control%tamm_dancoff)
THEN
1109 WRITE (unit=ou, fmt=
"(T3,A)") &
1110 "XAS_TDP| Tamm-Dancoff Approximation (TDA): On"
1112 WRITE (unit=ou, fmt=
"(T3,A)") &
1113 "XAS_TDP| Tamm-Dancoff Approximation (TDA): Off"
1117 IF (xas_tdp_control%dipole_form ==
xas_dip_vel)
THEN
1118 WRITE (unit=ou, fmt=
"(T3,A)") &
1119 "XAS_TDP| Transition Dipole Representation: VELOCITY"
1121 WRITE (unit=ou, fmt=
"(T3,A)") &
1122 "XAS_TDP| Transition Dipole Representation: LENGTH"
1126 IF (xas_tdp_control%do_quad)
THEN
1127 WRITE (unit=ou, fmt=
"(T3,A)") &
1128 "XAS_TDP| Transition Quadrupole: On"
1132 IF (xas_tdp_control%eps_pgf > 0.0_dp)
THEN
1133 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1134 "XAS_TDP| EPS_PGF_XAS: ", xas_tdp_control%eps_pgf
1136 WRITE (unit=ou, fmt=
"(T3,A,ES7.1,A)") &
1137 "XAS_TDP| EPS_PGF_XAS: ", dft_control%qs_control%eps_pgf_orb,
" (= EPS_PGF_ORB)"
1141 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1142 "XAS_TDP| EPS_FILTER: ", xas_tdp_control%eps_filter
1145 IF (xas_tdp_control%do_xc)
THEN
1146 WRITE (unit=ou, fmt=
"(T3,A)") &
1147 "XAS_TDP| Radial Grid(s) Info: Kind, na, nr"
1148 DO i = 1,
SIZE(xas_tdp_control%grid_info, 1)
1149 WRITE (unit=ou, fmt=
"(T3,A,A6,A,A,A,A)") &
1150 " ", trim(xas_tdp_control%grid_info(i, 1)),
", ", &
1151 trim(xas_tdp_control%grid_info(i, 2)),
", ", trim(xas_tdp_control%grid_info(i, 3))
1156 IF (.NOT. xas_tdp_control%do_coulomb)
THEN
1157 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1158 "XAS_TDP| No kernel (standard DFT)"
1162 IF (xas_tdp_control%do_xc)
THEN
1164 WRITE (unit=ou, fmt=
"(/,T3,A,F5.2,A)") &
1165 "XAS_TDP| RI Region's Radius: ", xas_tdp_control%ri_radius*
angstrom,
" Ang"
1167 WRITE (unit=ou, fmt=
"(T3,A,/)") &
1168 "XAS_TDP| XC Kernel Functional(s) used for the kernel:"
1170 IF (qs_env%do_rixs)
THEN
1175 CALL xc_write(ou, kernel_section, lsd=.true.)
1179 IF (xas_tdp_control%do_hfx)
THEN
1180 WRITE (unit=ou, fmt=
"(/,T3,A,/,/,T3,A,F5.3)") &
1181 "XAS_TDP| Exact Exchange Kernel: Yes ", &
1182 "EXACT_EXCHANGE| Scale: ", xas_tdp_control%sx
1184 WRITE (unit=ou, fmt=
"(T3,A)") &
1185 "EXACT_EXCHANGE| Potential : Coulomb"
1187 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,A)") &
1188 "EXACT_EXCHANGE| Potential: Truncated Coulomb", &
1189 "EXACT_EXCHANGE| Range: ", xas_tdp_control%x_potential%cutoff_radius*
angstrom,
", (Ang)", &
1190 "EXACT_EXCHANGE| T_C_G_DATA: ", trim(xas_tdp_control%x_potential%filename)
1192 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,F5.2,A,/,T3,A,ES7.1)") &
1193 "EXACT_EXCHANGE| Potential: Short Range", &
1194 "EXACT_EXCHANGE| Omega: ", xas_tdp_control%x_potential%omega,
", (1/a0)", &
1195 "EXACT_EXCHANGE| Effective Range: ", xas_tdp_control%x_potential%cutoff_radius*
angstrom,
", (Ang)", &
1196 "EXACT_EXCHANGE| EPS_RANGE: ", xas_tdp_control%eps_range
1198 IF (xas_tdp_control%eps_screen > 1.0e-16)
THEN
1199 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1200 "EXACT_EXCHANGE| EPS_SCREENING: ", xas_tdp_control%eps_screen
1204 IF (xas_tdp_control%do_ri_metric)
THEN
1206 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1207 "EXACT_EXCHANGE| Using a RI metric"
1208 IF (xas_tdp_control%ri_m_potential%potential_type ==
do_potential_id)
THEN
1209 WRITE (unit=ou, fmt=
"(T3,A)") &
1210 "EXACT_EXCHANGE RI_METRIC| Potential : Overlap"
1212 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,A)") &
1213 "EXACT_EXCHANGE RI_METRIC| Potential: Truncated Coulomb", &
1214 "EXACT_EXCHANGE RI_METRIC| Range: ", xas_tdp_control%ri_m_potential%cutoff_radius &
1216 "EXACT_EXCHANGE RI_METRIC| T_C_G_DATA: ", trim(xas_tdp_control%ri_m_potential%filename)
1218 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,F5.2,A,/,T3,A,ES7.1)") &
1219 "EXACT_EXCHANGE RI_METRIC| Potential: Short Range", &
1220 "EXACT_EXCHANGE RI_METRIC| Omega: ", xas_tdp_control%ri_m_potential%omega,
", (1/a0)", &
1221 "EXACT_EXCHANGE RI_METRIC| Effective Range: ", &
1222 xas_tdp_control%ri_m_potential%cutoff_radius*
angstrom,
", (Ang)", &
1223 "EXACT_EXCHANGE RI_METRIC| EPS_RANGE: ", xas_tdp_control%eps_range
1227 WRITE (unit=ou, fmt=
"(/,T3,A,/)") &
1228 "XAS_TDP| Exact Exchange Kernel: No "
1232 WRITE (unit=ou, fmt=
"(/,T3,A,F5.2)") &
1233 "XAS_TDP| Overlap matrix occupation: ", occ
1236 IF (xas_tdp_control%do_gw2x)
THEN
1237 WRITE (unit=ou, fmt=
"(T3,A,/)") &
1238 "XAS_TDP| GW2X correction enabled"
1240 IF (xas_tdp_control%xps_only)
THEN
1241 WRITE (unit=ou, fmt=
"(T3,A)") &
1242 "GW2X| Only computing ionizations potentials for XPS"
1245 IF (xas_tdp_control%pseudo_canonical)
THEN
1246 WRITE (unit=ou, fmt=
"(T3,A)") &
1247 "GW2X| Using the pseudo-canonical scheme"
1249 WRITE (unit=ou, fmt=
"(T3,A)") &
1250 "GW2X| Using the GW2X* scheme"
1253 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1254 "GW2X| EPS_GW2X: ", xas_tdp_control%gw2x_eps
1256 WRITE (unit=ou, fmt=
"(T3,A,I5)") &
1257 "GW2X| contraction batch size: ", xas_tdp_control%batch_size
1259 IF ((int(xas_tdp_control%c_os) /= 1) .OR. (int(xas_tdp_control%c_ss) /= 1))
THEN
1260 WRITE (unit=ou, fmt=
"(T3,A,F7.4,/,T3,A,F7.4)") &
1261 "GW2X| Same-spin scaling factor: ", xas_tdp_control%c_ss, &
1262 "GW2X| Opposite-spin scaling factor: ", xas_tdp_control%c_os
1267 END SUBROUTINE print_info
1282 SUBROUTINE assign_mos_to_ex_atoms(xas_tdp_env, xas_tdp_control, qs_env)
1288 INTEGER :: at_index, iat, iat_memo, imo, ispin, &
1289 n_atoms, n_search, nex_atoms, nspins
1290 INTEGER,
DIMENSION(3) :: perd_init
1291 INTEGER,
DIMENSION(:, :, :),
POINTER :: mos_of_ex_atoms
1292 REAL(
dp) :: dist, dist_min
1293 REAL(
dp),
DIMENSION(3) :: at_pos, r_ac, wfn_center
1298 NULLIFY (localized_wfn_control, mos_of_ex_atoms, cell, particle_set)
1301 mos_of_ex_atoms => xas_tdp_env%mos_of_ex_atoms
1302 mos_of_ex_atoms(:, :, :) = -1
1303 n_search = xas_tdp_control%n_search
1304 nex_atoms = xas_tdp_env%nex_atoms
1305 localized_wfn_control => xas_tdp_env%qs_loc_env%localized_wfn_control
1306 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, cell=cell)
1307 n_atoms =
SIZE(particle_set)
1308 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1311 perd_init = cell%perd
1315 DO ispin = 1, nspins
1316 DO imo = 1, n_search
1318 wfn_center(1:3) = localized_wfn_control%centers_set(ispin)%array(1:3, imo)
1322 dist_min = 10000.0_dp
1324 at_pos = particle_set(iat)%r
1325 r_ac =
pbc(at_pos, wfn_center, cell)
1329 IF (dist < dist_min)
THEN
1336 IF (any(xas_tdp_env%ex_atom_indices == iat_memo))
THEN
1337 at_index =
locate(xas_tdp_env%ex_atom_indices, iat_memo)
1338 mos_of_ex_atoms(imo, at_index, ispin) = 1
1344 cell%perd = perd_init
1346 END SUBROUTINE assign_mos_to_ex_atoms
1358 SUBROUTINE reinit_qs_loc_env(qs_loc_env, n_loc_states, do_uks, qs_env)
1361 INTEGER,
INTENT(IN) :: n_loc_states
1362 LOGICAL,
INTENT(IN) :: do_uks
1365 INTEGER :: i, nspins
1374 loc_wfn_control => qs_loc_env%localized_wfn_control
1379 loc_wfn_control%nloc_states(:) = n_loc_states
1380 loc_wfn_control%eps_occ = 0.0_dp
1381 loc_wfn_control%lu_bound_states(1, :) = 1
1382 loc_wfn_control%lu_bound_states(2, :) = n_loc_states
1384 loc_wfn_control%do_homo = .true.
1385 ALLOCATE (loc_wfn_control%loc_states(n_loc_states, 2))
1386 DO i = 1, n_loc_states
1387 loc_wfn_control%loc_states(i, :) = i
1390 nspins = 1;
IF (do_uks) nspins = 2
1391 CALL set_loc_centers(loc_wfn_control, loc_wfn_control%nloc_states, nspins=nspins)
1394 CALL qs_loc_env_init(qs_loc_env, loc_wfn_control, qs_env, do_localize=.true.)
1396 CALL qs_loc_env_init(qs_loc_env, loc_wfn_control, qs_env, myspin=1, do_localize=.true.)
1399 END SUBROUTINE reinit_qs_loc_env
1409 SUBROUTINE diagonalize_assigned_mo_subset(xas_tdp_env, xas_tdp_control, qs_env)
1415 INTEGER :: i, iat, ilmo, ispin, nao, nlmo, nspins
1416 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: evals
1419 TYPE(
cp_fm_type) :: evecs, ks_fm, lmo_fm, work
1425 NULLIFY (mos, mo_coeff, matrix_ks, para_env, blacs_env, lmo_struct, ks_struct)
1428 CALL get_qs_env(qs_env, mos=mos, matrix_ks=matrix_ks, para_env=para_env, blacs_env=blacs_env)
1430 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1433 DO ispin = 1, nspins
1434 DO iat = 1, xas_tdp_env%nex_atoms
1437 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, nao=nao)
1440 nlmo = count(xas_tdp_env%mos_of_ex_atoms(:, iat, ispin) == 1)
1442 para_env=para_env, context=blacs_env)
1447 para_env=para_env, context=blacs_env)
1453 DO ilmo = 1, xas_tdp_control%n_search
1454 IF (xas_tdp_env%mos_of_ex_atoms(ilmo, iat, ispin) == -1) cycle
1459 s_firstcol=ilmo, t_firstrow=1, t_firstcol=i)
1465 CALL parallel_gemm(
'T',
'N', nlmo, nlmo, nao, 1.0_dp, lmo_fm, work, 0.0_dp, ks_fm)
1468 ALLOCATE (evals(nlmo))
1473 CALL parallel_gemm(
'N',
'N', nao, nlmo, nlmo, 1.0_dp, lmo_fm, evecs, 0.0_dp, work)
1477 DO ilmo = 1, xas_tdp_control%n_search
1478 IF (xas_tdp_env%mos_of_ex_atoms(ilmo, iat, ispin) == -1) cycle
1482 s_firstcol=i, t_firstrow=1, t_firstcol=ilmo)
1496 END SUBROUTINE diagonalize_assigned_mo_subset
1507 SUBROUTINE assign_mos_to_donor_state(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
1514 INTEGER :: at_index, i, iat, imo, ispin, l, my_mo, &
1515 n_search, n_states, nao, ndo_so, nj, &
1516 nsgf_kind, nsgf_sto, nspins, &
1518 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: my_mos
1519 INTEGER,
DIMENSION(2) :: next_best_overlap_ind
1520 INTEGER,
DIMENSION(4, 7) :: ne
1521 INTEGER,
DIMENSION(:),
POINTER :: first_sgf, lq, nq
1522 INTEGER,
DIMENSION(:, :, :),
POINTER :: mos_of_ex_atoms
1525 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) ::
diag, overlap, sto_overlap
1526 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: max_overlap
1527 REAL(
dp),
DIMENSION(2) :: next_best_overlap
1528 REAL(
dp),
DIMENSION(:),
POINTER :: mo_evals, zeta
1529 REAL(
dp),
DIMENSION(:, :),
POINTER :: overlap_matrix, tmp_coeff
1533 TYPE(
cp_fm_type),
POINTER :: gs_coeffs, mo_coeff
1539 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
1542 NULLIFY (sto_basis_set, sto_to_gto_basis_set, qs_kind_set, kind_basis_set, lq, nq, zeta)
1543 NULLIFY (overlap_matrix, mos, mo_coeff, mos_of_ex_atoms, tmp_coeff, first_sgf, particle_set)
1544 NULLIFY (mo_evals, matrix_ks, para_env, blacs_env)
1545 NULLIFY (eval_mat_struct, gs_struct, gs_coeffs)
1549 CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set, mos=mos, particle_set=particle_set, &
1550 matrix_ks=matrix_ks, para_env=para_env, blacs_env=blacs_env)
1552 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1563 ELSE IF (donor_state%state_type ==
xas_2s_type)
THEN
1567 ELSE IF (donor_state%state_type ==
xas_2p_type)
THEN
1572 cpabort(
"Procedure for required type not implemented")
1574 ALLOCATE (my_mos(n_states, nspins))
1575 ALLOCATE (max_overlap(n_states, nspins))
1578 CALL get_qs_kind(qs_kind_set(donor_state%kind_index), zeff=zeff)
1586 ne(l, i) =
ptable(zval)%e_conv(l - 1) - 2*nj*(i - l)
1587 ne(l, i) = max(ne(l, i), 0)
1588 ne(l, i) = min(ne(l, i), 2*nj)
1593 zeta(1) =
srules(zval, ne, nq(1), lq(1))
1600 DEALLOCATE (nq, lq, zeta)
1604 gto_basis_set=sto_to_gto_basis_set, &
1606 sto_to_gto_basis_set%norm_type = 2
1610 CALL get_qs_kind(qs_kind_set(donor_state%kind_index), basis_set=kind_basis_set)
1615 ALLOCATE (overlap_matrix(nsgf_sto, nsgf_kind))
1625 mos_of_ex_atoms => xas_tdp_env%mos_of_ex_atoms
1626 n_search = xas_tdp_control%n_search
1627 at_index = donor_state%at_index
1628 iat =
locate(xas_tdp_env%ex_atom_indices, at_index)
1629 ALLOCATE (first_sgf(
SIZE(particle_set)))
1630 CALL get_particle_set(particle_set=particle_set, qs_kind_set=qs_kind_set, first_sgf=first_sgf)
1631 ALLOCATE (tmp_coeff(nsgf_kind, 1))
1632 ALLOCATE (sto_overlap(nsgf_kind))
1633 ALLOCATE (overlap(n_search))
1635 next_best_overlap = 0.0_dp
1636 max_overlap = 0.0_dp
1638 DO ispin = 1, nspins
1640 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, nao=nao)
1644 DO imo = 1, n_search
1645 IF (mos_of_ex_atoms(imo, iat, ispin) > 0)
THEN
1647 sto_overlap = 0.0_dp
1651 CALL cp_fm_get_submatrix(fm=mo_coeff, target_m=tmp_coeff, start_row=first_sgf(at_index), &
1652 start_col=imo, n_rows=nsgf_kind, n_cols=1, transpose=.false.)
1655 CALL dgemm(
'N',
'N', nsgf_sto, 1, nsgf_kind, 1.0_dp, overlap_matrix, nsgf_sto, &
1656 tmp_coeff, nsgf_kind, 0.0_dp, sto_overlap, nsgf_sto)
1661 overlap(imo) = sum(abs(sto_overlap))
1668 my_mo = maxloc(overlap, 1)
1669 my_mos(i, ispin) = my_mo
1670 max_overlap(i, ispin) = maxval(overlap, 1)
1671 overlap(my_mo) = 0.0_dp
1674 next_best_overlap(ispin) = maxval(overlap, 1)
1675 next_best_overlap_ind(ispin) = maxloc(overlap, 1)
1683 DEALLOCATE (overlap_matrix, tmp_coeff)
1686 IF (all(my_mos > 0) .AND. all(my_mos <= n_search))
THEN
1688 ALLOCATE (donor_state%mo_indices(n_states, nspins))
1689 donor_state%mo_indices = my_mos
1690 donor_state%ndo_mo = n_states
1694 para_env=para_env, context=blacs_env)
1695 ALLOCATE (donor_state%gs_coeffs)
1698 IF (.NOT.
ASSOCIATED(xas_tdp_env%mo_coeff))
THEN
1699 ALLOCATE (xas_tdp_env%mo_coeff(nspins))
1702 DO ispin = 1, nspins
1703 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff)
1705 IF (.NOT.
ASSOCIATED(xas_tdp_env%mo_coeff(ispin)%local_data))
THEN
1708 matrix_struct=matrix_struct)
1709 CALL cp_fm_create(xas_tdp_env%mo_coeff(ispin), matrix_struct)
1710 CALL cp_fm_to_fm(mo_coeff, xas_tdp_env%mo_coeff(ispin))
1715 ncol=1, s_firstrow=1, s_firstcol=my_mos(i, ispin), &
1716 t_firstrow=1, t_firstcol=(ispin - 1)*n_states + i)
1719 gs_coeffs => donor_state%gs_coeffs
1722 ALLOCATE (donor_state%contract_coeffs(nsgf_kind, n_states*nspins))
1723 CALL cp_fm_get_submatrix(gs_coeffs, donor_state%contract_coeffs, start_row=first_sgf(at_index), &
1724 start_col=1, n_rows=nsgf_kind, n_cols=n_states*nspins)
1729 IF (.NOT. xas_tdp_control%do_loc .AND. .NOT. xas_tdp_control%do_roks)
THEN
1730 IF (output_unit > 0)
THEN
1731 WRITE (unit=output_unit, fmt=
"(T5,A,/,T5,A,/,T5,A)") &
1732 "The following canonical MO(s) have been associated with the donor state(s)", &
1733 "based on the overlap with the components of a minimal STO basis: ", &
1734 " Spin MO index overlap(sum)"
1737 ALLOCATE (donor_state%energy_evals(n_states, nspins))
1738 donor_state%energy_evals = 0.0_dp
1741 DO ispin = 1, nspins
1742 CALL get_mo_set(mos(ispin), eigenvalues=mo_evals)
1744 donor_state%energy_evals(i, ispin) = mo_evals(my_mos(i, ispin))
1746 IF (output_unit > 0)
THEN
1747 WRITE (unit=output_unit, fmt=
"(T46,I4,I11,F17.5)") &
1748 ispin, my_mos(i, ispin), max_overlap(i, ispin)
1756 IF (output_unit > 0)
THEN
1757 WRITE (unit=output_unit, fmt=
"(T5,A,/,T5,A,/,T5,A)") &
1758 "The following localized MO(s) have been associated with the donor state(s)", &
1759 "based on the overlap with the components of a minimal STO basis: ", &
1760 " Spin MO index overlap(sum)"
1764 DO ispin = 1, nspins
1768 IF (output_unit > 0)
THEN
1769 WRITE (unit=output_unit, fmt=
"(T46,I4,I11,F17.5)") &
1770 ispin, my_mos(i, ispin), max_overlap(i, ispin)
1778 ndo_so = nspins*n_states
1781 para_env=para_env, context=blacs_env)
1783 ALLOCATE (
diag(ndo_so))
1785 IF (.NOT. xas_tdp_control%do_roks)
THEN
1787 ALLOCATE (donor_state%energy_evals(n_states, nspins))
1788 donor_state%energy_evals = 0.0_dp
1791 DO ispin = 1, nspins
1793 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((ispin - 1)*n_states + 1:ispin*n_states)
1803 ALLOCATE (donor_state%energy_evals(n_states, 2))
1804 donor_state%energy_evals = 0.0_dp
1809 CALL parallel_gemm(
'T',
'N', ndo_so, ndo_so, nao, 1.0_dp, gs_coeffs, work_mat, 0.0_dp, eval_mat)
1812 donor_state%energy_evals(:, ispin) =
diag(:)
1827 ALLOCATE (donor_state%gw2x_evals(
SIZE(donor_state%energy_evals, 1),
SIZE(donor_state%energy_evals, 2)))
1828 donor_state%gw2x_evals(:, :) = donor_state%energy_evals(:, :)
1832 DEALLOCATE (first_sgf)
1834 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T5,A)")
" "
1836 DO ispin = 1, nspins
1837 IF (output_unit > 0)
THEN
1838 WRITE (unit=output_unit, fmt=
"(T5,A,I1,A,F7.5,A,I4)") &
1839 "The next best overlap for spin ", ispin,
" is ", next_best_overlap(ispin), &
1840 " for MO with index ", next_best_overlap_ind(ispin)
1843 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T5,A)")
" "
1846 cpabort(
"A core donor state could not be assigned MO(s). Increasing NSEARCH might help.")
1849 END SUBROUTINE assign_mos_to_donor_state
1859 SUBROUTINE find_mo_centers(xas_tdp_env, xas_tdp_control, qs_env)
1865 INTEGER :: dim_op, i, ispin, j, n_centers, nao, &
1867 REAL(
dp),
DIMENSION(6) :: weights
1872 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:, :) :: zij_fm_set
1873 TYPE(
cp_fm_type),
DIMENSION(:),
POINTER :: moloc_coeff
1875 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: op_sm_set
1880 NULLIFY (qs_loc_env, cell, print_loc_section, op_sm_set, moloc_coeff, vectors)
1881 NULLIFY (tmp_fm_struct, para_env, blacs_env, prog_run_info)
1884 print_loc_section => xas_tdp_control%print_loc_subsection
1885 n_centers = xas_tdp_control%n_search
1886 CALL get_qs_env(qs_env=qs_env, para_env=para_env, blacs_env=blacs_env, cell=cell)
1894 CALL reinit_qs_loc_env(xas_tdp_env%qs_loc_env, n_centers, xas_tdp_control%do_uks, qs_env)
1895 qs_loc_env => xas_tdp_env%qs_loc_env
1898 CALL get_qs_loc_env(qs_loc_env=qs_loc_env, weights=weights, op_sm_set=op_sm_set, &
1899 moloc_coeff=moloc_coeff)
1902 vectors => moloc_coeff(1)
1907 ncol_global=n_centers, nrow_global=n_centers)
1909 IF (cell%orthorhombic)
THEN
1914 ALLOCATE (zij_fm_set(2, dim_op))
1922 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1924 DO ispin = 1, nspins
1926 vectors => moloc_coeff(ispin)
1931 CALL parallel_gemm(
"T",
"N", n_centers, n_centers, nao, 1.0_dp, vectors, opvec, 0.0_dp, &
1938 cell=cell, weights=weights, ispin=ispin, &
1939 print_loc_section=print_loc_section, only_initial_out=.true.)
1948 qs_loc_env%do_localize = xas_tdp_control%do_loc
1950 END SUBROUTINE find_mo_centers
1959 SUBROUTINE print_checks(xas_tdp_env, xas_tdp_control, qs_env)
1965 CHARACTER(LEN=default_string_length) :: kind_name
1966 INTEGER :: current_state_index, iat, iatom, ikind, &
1967 istate, output_unit, tmp_index
1968 INTEGER,
DIMENSION(:),
POINTER :: atoms_of_kind
1972 NULLIFY (atomic_kind_set, atoms_of_kind, current_state)
1976 IF (output_unit > 0)
THEN
1977 WRITE (output_unit,
"(/,T3,A,/,T3,A,/,T3,A)") &
1978 "# Check the donor states for their quality. They need to have a well defined type ", &
1979 " (1s, 2s, etc) which is indicated by the overlap. They also need to be localized, ", &
1980 " for which the Mulliken population analysis is one indicator (must be close to 1.0)"
1984 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
1985 current_state_index = 1
1988 DO ikind = 1,
SIZE(atomic_kind_set)
1990 CALL get_atomic_kind(atomic_kind=atomic_kind_set(ikind), name=kind_name, &
1991 atom_list=atoms_of_kind)
1993 IF (.NOT. any(xas_tdp_env%ex_kind_indices == ikind)) cycle
1996 DO iat = 1,
SIZE(atoms_of_kind)
1997 iatom = atoms_of_kind(iat)
1999 IF (.NOT. any(xas_tdp_env%ex_atom_indices == iatom)) cycle
2000 tmp_index =
locate(xas_tdp_env%ex_atom_indices, iatom)
2003 DO istate = 1,
SIZE(xas_tdp_env%state_types, 1)
2005 IF (xas_tdp_env%state_types(istate, tmp_index) ==
xas_not_excited) cycle
2007 current_state => xas_tdp_env%donor_states(current_state_index)
2009 at_symbol=kind_name, kind_index=ikind, &
2010 state_type=xas_tdp_env%state_types(istate, tmp_index))
2012 IF (output_unit > 0)
THEN
2013 WRITE (output_unit,
"(/,T4,A,A2,A,I4,A,A,A)") &
2014 "-Donor state of type ", xas_tdp_env%state_type_char(current_state%state_type), &
2015 " for atom", current_state%at_index,
" of kind ", trim(current_state%at_symbol),
":"
2019 CALL assign_mos_to_donor_state(current_state, xas_tdp_env, xas_tdp_control, qs_env)
2020 CALL perform_mulliken_on_donor_state(current_state, qs_env)
2022 current_state_index = current_state_index + 1
2023 NULLIFY (current_state)
2029 IF (output_unit > 0)
THEN
2030 WRITE (output_unit,
"(/,T5,A)") &
2031 "Use LOCALIZE and/or increase N_SEARCH for better results, if so required."
2034 END SUBROUTINE print_checks
2044 SUBROUTINE compute_lenrep_multipole(iatom, xas_tdp_env, xas_tdp_control, qs_env)
2046 INTEGER,
INTENT(IN) :: iatom
2052 REAL(
dp),
DIMENSION(3) :: rc
2056 NULLIFY (work, particle_set)
2058 CALL get_qs_env(qs_env, particle_set=particle_set)
2059 rc = particle_set(iatom)%r
2062 IF (xas_tdp_control%dipole_form ==
xas_dip_len)
THEN
2064 CALL dbcsr_set(xas_tdp_env%dipmat(i)%matrix, 0.0_dp)
2065 work(i)%matrix => xas_tdp_env%dipmat(i)%matrix
2069 IF (xas_tdp_control%do_quad)
THEN
2071 CALL dbcsr_set(xas_tdp_env%quadmat(i)%matrix, 0.0_dp)
2072 work(3 + i)%matrix => xas_tdp_env%quadmat(i)%matrix
2075 IF (xas_tdp_control%dipole_form ==
xas_dip_vel) order = -2
2079 CALL rrc_xyz_ao(work, qs_env, rc, order=order, minimum_image=.true.)
2082 END SUBROUTINE compute_lenrep_multipole
2096 SUBROUTINE compute_dipole_fosc(donor_state, xas_tdp_control, xas_tdp_env)
2102 CHARACTER(len=*),
PARAMETER :: routinen =
'compute_dipole_fosc'
2104 INTEGER :: handle, iosc, j, nao, ndo_mo, ndo_so, &
2106 LOGICAL :: do_sc, do_sg
2107 REAL(
dp) :: alpha_xyz, beta_xyz, osc_xyz, pref
2108 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: alpha_contr, beta_contr, tot_contr
2109 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: dip_block
2110 REAL(
dp),
DIMENSION(:),
POINTER :: lr_evals
2111 REAL(
dp),
DIMENSION(:, :),
POINTER :: alpha_osc, beta_osc, osc_str
2119 NULLIFY (dipmat, col_struct, mat_struct, para_env, blacs_env, lr_coeffs)
2120 NULLIFY (lr_evals, osc_str, alpha_osc, beta_osc)
2122 CALL timeset(routinen, handle)
2125 do_sc = xas_tdp_control%do_spin_cons
2126 do_sg = xas_tdp_control%do_singlet
2129 lr_evals => donor_state%sc_evals
2130 lr_coeffs => donor_state%sc_coeffs
2131 ELSE IF (do_sg)
THEN
2133 lr_evals => donor_state%sg_evals
2134 lr_coeffs => donor_state%sg_coeffs
2136 cpabort(
"Dipole oscilaltor strength only for singlets and spin-conserving excitations.")
2138 ndo_mo = donor_state%ndo_mo
2139 ndo_so = ndo_mo*nspins
2140 ngs = ndo_so;
IF (xas_tdp_control%do_roks) ngs = ndo_mo
2141 nosc =
SIZE(lr_evals)
2142 ALLOCATE (donor_state%osc_str(nosc, 4), donor_state%alpha_osc(nosc, 4), donor_state%beta_osc(nosc, 4))
2143 osc_str => donor_state%osc_str
2144 alpha_osc => donor_state%alpha_osc
2145 beta_osc => donor_state%beta_osc
2149 dipmat => xas_tdp_env%dipmat
2152 CALL cp_fm_get_info(donor_state%gs_coeffs, matrix_struct=col_struct, para_env=para_env, &
2153 context=blacs_env, nrow_global=nao)
2155 nrow_global=ndo_so*nosc, ncol_global=ngs)
2159 ALLOCATE (tot_contr(ndo_mo), dip_block(ndo_so, ngs), alpha_contr(ndo_mo), beta_contr(ndo_mo))
2160 pref = 2.0_dp;
IF (do_sc) pref = 1.0_dp
2168 CALL parallel_gemm(
'T',
'N', ndo_so*nosc, ngs, nao, 1.0_dp, lr_coeffs, col_work, 0.0_dp, mat_work)
2174 CALL cp_fm_get_submatrix(fm=mat_work, target_m=dip_block, start_row=(iosc - 1)*ndo_so + 1, &
2175 start_col=1, n_rows=ndo_so, n_cols=ngs)
2178 ELSE IF (do_sc .AND. xas_tdp_control%do_uks)
THEN
2179 alpha_contr(:) =
get_diag(dip_block(1:ndo_mo, 1:ndo_mo))
2180 beta_contr(:) =
get_diag(dip_block(ndo_mo + 1:ndo_so, ndo_mo + 1:ndo_so))
2181 tot_contr(:) = alpha_contr(:) + beta_contr(:)
2184 alpha_contr(:) =
get_diag(dip_block(1:ndo_mo, :))
2185 beta_contr(:) =
get_diag(dip_block(ndo_mo + 1:ndo_so, :))
2186 tot_contr(:) = alpha_contr(:) + beta_contr(:)
2189 osc_xyz = sum(tot_contr)**2
2190 alpha_xyz = sum(alpha_contr)**2
2191 beta_xyz = sum(beta_contr)**2
2193 alpha_osc(iosc, 4) = alpha_osc(iosc, 4) + alpha_xyz
2194 alpha_osc(iosc, j) = alpha_xyz
2196 beta_osc(iosc, 4) = beta_osc(iosc, 4) + beta_xyz
2197 beta_osc(iosc, j) = beta_xyz
2199 osc_str(iosc, 4) = osc_str(iosc, 4) + osc_xyz
2200 osc_str(iosc, j) = osc_xyz
2207 IF (xas_tdp_control%dipole_form ==
xas_dip_len)
THEN
2208 osc_str(:, j) = pref*2.0_dp/3.0_dp*lr_evals(:)*osc_str(:, j)
2209 alpha_osc(:, j) = pref*2.0_dp/3.0_dp*lr_evals(:)*alpha_osc(:, j)
2210 beta_osc(:, j) = pref*2.0_dp/3.0_dp*lr_evals(:)*beta_osc(:, j)
2212 osc_str(:, j) = pref*2.0_dp/3.0_dp/lr_evals(:)*osc_str(:, j)
2213 alpha_osc(:, j) = pref*2.0_dp/3.0_dp/lr_evals(:)*alpha_osc(:, j)
2214 beta_osc(:, j) = pref*2.0_dp/3.0_dp/lr_evals(:)*beta_osc(:, j)
2223 CALL timestop(handle)
2225 END SUBROUTINE compute_dipole_fosc
2235 SUBROUTINE compute_quadrupole_fosc(donor_state, xas_tdp_control, xas_tdp_env)
2241 CHARACTER(len=*),
PARAMETER :: routinen =
'compute_quadrupole_fosc'
2243 INTEGER :: handle, iosc, j, nao, ndo_mo, ndo_so, &
2245 LOGICAL :: do_sc, do_sg
2247 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: tot_contr, trace
2248 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: quad_block
2249 REAL(
dp),
DIMENSION(:),
POINTER :: lr_evals, osc_str
2257 NULLIFY (lr_evals, osc_str, lr_coeffs, col_struct, mat_struct, para_env)
2260 CALL timeset(routinen, handle)
2263 do_sc = xas_tdp_control%do_spin_cons
2264 do_sg = xas_tdp_control%do_singlet
2267 lr_evals => donor_state%sc_evals
2268 lr_coeffs => donor_state%sc_coeffs
2269 ELSE IF (do_sg)
THEN
2271 lr_evals => donor_state%sg_evals
2272 lr_coeffs => donor_state%sg_coeffs
2274 cpabort(
"Quadrupole oscillator strengths only for singlet and spin-conserving excitations")
2276 ndo_mo = donor_state%ndo_mo
2277 ndo_so = ndo_mo*nspins
2278 ngs = ndo_so;
IF (xas_tdp_control%do_roks) ngs = ndo_mo
2279 nosc =
SIZE(lr_evals)
2280 ALLOCATE (donor_state%quad_osc_str(nosc))
2281 osc_str => donor_state%quad_osc_str
2283 quadmat => xas_tdp_env%quadmat
2286 CALL cp_fm_get_info(donor_state%gs_coeffs, matrix_struct=col_struct, para_env=para_env, &
2287 context=blacs_env, nrow_global=nao)
2289 nrow_global=ndo_so*nosc, ncol_global=ngs)
2293 ALLOCATE (quad_block(ndo_so, ngs), tot_contr(ndo_mo))
2294 pref = 2.0_dp;
IF (do_sc) pref = 1.0_dp
2295 ALLOCATE (trace(nosc))
2304 CALL parallel_gemm(
'T',
'N', ndo_so*nosc, ngs, nao, 1.0_dp, lr_coeffs, col_work, 0.0_dp, mat_work)
2310 CALL cp_fm_get_submatrix(fm=mat_work, target_m=quad_block, start_row=(iosc - 1)*ndo_so + 1, &
2311 start_col=1, n_rows=ndo_so, n_cols=ngs)
2314 tot_contr(:) =
get_diag(quad_block)
2315 ELSE IF (do_sc .AND. xas_tdp_control%do_uks)
THEN
2316 tot_contr(:) =
get_diag(quad_block(1:ndo_mo, 1:ndo_mo))
2317 tot_contr(:) = tot_contr(:) +
get_diag(quad_block(ndo_mo + 1:ndo_so, ndo_mo + 1:ndo_so))
2320 tot_contr(:) =
get_diag(quad_block(1:ndo_mo, :))
2321 tot_contr(:) = tot_contr(:) +
get_diag(quad_block(ndo_mo + 1:ndo_so, :))
2325 IF (j == 1 .OR. j == 4 .OR. j == 6)
THEN
2326 osc_str(iosc) = osc_str(iosc) + sum(tot_contr)**2
2327 trace(iosc) = trace(iosc) + sum(tot_contr)
2331 osc_str(iosc) = osc_str(iosc) + 2.0_dp*sum(tot_contr)**2
2338 osc_str(:) = pref*1._dp/20._dp*
a_fine**2*lr_evals(:)**3*(osc_str(:) - 1._dp/3._dp*trace(:)**2)
2345 CALL timestop(handle)
2347 END SUBROUTINE compute_quadrupole_fosc
2356 SUBROUTINE write_mos_to_ex_atoms_association(xas_tdp_env, xas_tdp_control, qs_env)
2362 CHARACTER(LEN=default_string_length) :: kind_name
2363 INTEGER :: at_index, imo, ispin, nmo, nspins, &
2364 output_unit, tmp_index
2365 INTEGER,
DIMENSION(3) :: perd_init
2366 INTEGER,
DIMENSION(:),
POINTER :: ex_atom_indices
2367 INTEGER,
DIMENSION(:, :, :),
POINTER :: mos_of_ex_atoms
2368 REAL(
dp) :: dist, mo_spread
2369 REAL(
dp),
DIMENSION(3) :: at_pos, r_ac, wfn_center
2373 NULLIFY (cell, particle_set, mos_of_ex_atoms, ex_atom_indices)
2377 IF (output_unit > 0)
THEN
2378 WRITE (unit=output_unit, fmt=
"(/,T3,A,/,T3,A,/,T3,A)") &
2379 " Associated Associated Distance to MO spread (Ang^2)", &
2380 "Spin MO index atom index atom kind MO center (Ang) -w_i ln(|z_ij|^2)", &
2381 "---------------------------------------------------------------------------------"
2385 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
2386 mos_of_ex_atoms => xas_tdp_env%mos_of_ex_atoms
2387 ex_atom_indices => xas_tdp_env%ex_atom_indices
2388 nmo = xas_tdp_control%n_search
2389 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, cell=cell)
2392 perd_init = cell%perd
2397 DO ispin = 1, nspins
2400 IF (any(mos_of_ex_atoms(imo, :, ispin) == 1))
THEN
2401 tmp_index = maxloc(mos_of_ex_atoms(imo, :, ispin), 1)
2402 at_index = ex_atom_indices(tmp_index)
2403 kind_name = particle_set(at_index)%atomic_kind%name
2405 at_pos = particle_set(at_index)%r
2406 wfn_center = xas_tdp_env%qs_loc_env%localized_wfn_control%centers_set(ispin)%array(1:3, imo)
2407 r_ac =
pbc(at_pos, wfn_center, cell)
2412 mo_spread = xas_tdp_env%qs_loc_env%localized_wfn_control%centers_set(ispin)%array(4, imo)
2415 IF (output_unit > 0)
THEN
2416 WRITE (unit=output_unit, fmt=
"(T3,I4,I10,I14,A14,ES19.3,ES20.3)") &
2417 ispin, imo, at_index, trim(kind_name), dist, mo_spread
2424 IF (output_unit > 0)
THEN
2425 WRITE (unit=output_unit, fmt=
"(T3,A,/)") &
2426 "---------------------------------------------------------------------------------"
2430 cell%perd = perd_init
2432 END SUBROUTINE write_mos_to_ex_atoms_association
2443 SUBROUTINE perform_mulliken_on_donor_state(donor_state, qs_env)
2447 INTEGER :: at_index, i, ispin, nao, natom, ndo_mo, &
2448 ndo_so, nsgf, nspins, output_unit
2449 INTEGER,
DIMENSION(:),
POINTER :: first_sgf, last_sgf
2450 INTEGER,
DIMENSION(:, :),
POINTER :: mo_indices
2451 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: mul_pop, pop_mat
2452 REAL(
dp),
DIMENSION(:, :),
POINTER :: work_array
2460 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2462 NULLIFY (mo_indices, qs_kind_set, particle_set, first_sgf, work_array)
2463 NULLIFY (matrix_s, para_env, blacs_env, col_vect_struct, last_sgf)
2466 at_index = donor_state%at_index
2467 mo_indices => donor_state%mo_indices
2468 ndo_mo = donor_state%ndo_mo
2469 gs_coeffs => donor_state%gs_coeffs
2471 nspins = 1;
IF (
SIZE(mo_indices, 2) == 2) nspins = 2
2472 ndo_so = ndo_mo*nspins
2473 ALLOCATE (mul_pop(ndo_mo, nspins))
2476 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, qs_kind_set=qs_kind_set, &
2477 para_env=para_env, blacs_env=blacs_env, matrix_s=matrix_s)
2478 CALL cp_fm_get_info(gs_coeffs, nrow_global=nao, matrix_struct=col_vect_struct)
2480 natom =
SIZE(particle_set, 1)
2481 ALLOCATE (first_sgf(natom))
2482 ALLOCATE (last_sgf(natom))
2484 CALL get_particle_set(particle_set, qs_kind_set, first_sgf=first_sgf, last_sgf=last_sgf)
2485 nsgf = last_sgf(at_index) - first_sgf(at_index) + 1
2493 ALLOCATE (work_array(nsgf, ndo_so))
2494 ALLOCATE (pop_mat(ndo_so, ndo_so))
2496 CALL cp_fm_get_submatrix(fm=work_vect, target_m=work_array, start_row=first_sgf(at_index), &
2497 start_col=1, n_rows=nsgf, n_cols=ndo_so, transpose=.false.)
2499 CALL dgemm(
'T',
'N', ndo_so, ndo_so, nsgf, 1.0_dp, donor_state%contract_coeffs, nsgf, &
2500 work_array, nsgf, 0.0_dp, pop_mat, ndo_so)
2503 DO ispin = 1, nspins
2505 mul_pop(i, ispin) = pop_mat((ispin - 1)*ndo_mo + i, (ispin - 1)*ndo_mo + i)
2510 IF (output_unit > 0)
THEN
2511 WRITE (unit=output_unit, fmt=
"(T5,A,/,T5,A)") &
2512 "Mulliken population analysis retricted to the associated MO(s) yields: ", &
2513 " Spin MO index charge"
2514 DO ispin = 1, nspins
2516 WRITE (unit=output_unit, fmt=
"(T51,I4,I10,F11.3)") &
2517 ispin, mo_indices(i, ispin), mul_pop(i, ispin)
2523 DEALLOCATE (first_sgf, last_sgf, work_array)
2526 END SUBROUTINE perform_mulliken_on_donor_state
2536 SUBROUTINE xas_tdp_post(ex_type, donor_state, xas_tdp_env, xas_tdp_section, qs_env)
2538 INTEGER,
INTENT(IN) :: ex_type
2544 CHARACTER(len=*),
PARAMETER :: routinen =
'xas_tdp_post'
2546 CHARACTER(len=default_string_length) :: domo, domon, excite, pos, xas_mittle
2547 INTEGER :: ex_state_idx, handle, ic, ido_mo, imo, irep, ispin, n_dependent, n_rep, nao, &
2548 ncubes, ndo_mo, ndo_so, nlumo, nmo, nspins, output_unit
2549 INTEGER,
DIMENSION(:),
POINTER :: bounds,
list, state_list
2550 LOGICAL :: append_cube, do_cubes, do_pdos, &
2552 REAL(
dp),
DIMENSION(:),
POINTER :: lr_evals
2553 REAL(
dp),
DIMENSION(:, :),
POINTER :: centers
2565 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2568 NULLIFY (atomic_kind_set, particle_set, qs_kind_set, mo_set, lr_evals, lr_coeffs)
2569 NULLIFY (mo_struct, para_env, blacs_env, fm_struct, matrix_s, print_key, logger)
2570 NULLIFY (bounds, state_list,
list, mos)
2574 do_pdos = .false.; do_cubes = .false.; do_wfn_restart = .false.
2577 "PRINT%PDOS"),
cp_p_file)) do_pdos = .true.
2580 "PRINT%CUBES"),
cp_p_file)) do_cubes = .true.
2583 "PRINT%RESTART_WFN"),
cp_p_file)) do_wfn_restart = .true.
2585 IF (.NOT. (do_pdos .OR. do_cubes .OR. do_wfn_restart))
RETURN
2587 CALL timeset(routinen, handle)
2590 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, particle_set=particle_set, &
2591 qs_kind_set=qs_kind_set, para_env=para_env, blacs_env=blacs_env, &
2592 matrix_s=matrix_s, mos=mos)
2594 SELECT CASE (ex_type)
2596 lr_evals => donor_state%sc_evals
2597 lr_coeffs => donor_state%sc_coeffs
2601 lr_evals => donor_state%sf_evals
2602 lr_coeffs => donor_state%sf_coeffs
2606 lr_evals => donor_state%sg_evals
2607 lr_coeffs => donor_state%sg_coeffs
2611 lr_evals => donor_state%tp_evals
2612 lr_coeffs => donor_state%tp_coeffs
2617 SELECT CASE (donor_state%state_type)
2626 ndo_mo = donor_state%ndo_mo
2627 ndo_so = ndo_mo*nspins
2628 nmo =
SIZE(lr_evals)
2632 nrow_global=nao, ncol_global=nmo)
2636 IF (do_wfn_restart)
THEN
2639 IF (.NOT. (nspins == 1 .AND. donor_state%state_type ==
xas_1s_type))
THEN
2640 cpabort(
"RESTART.wfn file only available for RKS K-edge XAS spectroscopy")
2643 CALL section_vals_val_get(xas_tdp_section,
"PRINT%RESTART_WFN%EXCITED_STATE_INDEX", n_rep_val=n_rep)
2647 i_rep_val=irep, i_val=ex_state_idx)
2648 cpassert(ex_state_idx <=
SIZE(lr_evals))
2653 IF (
SIZE(mos) == 1) &
2654 restart_mos(ispin)%occupation_numbers = mos(1)%occupation_numbers/2
2657 CALL cp_fm_to_fm_submat(msource=lr_coeffs, mtarget=restart_mos(1)%mo_coeff, nrow=nao, &
2658 ncol=1, s_firstrow=1, s_firstcol=ex_state_idx, t_firstrow=1, &
2659 t_firstcol=donor_state%mo_indices(1, 1))
2661 xas_mittle =
'xasat'//trim(adjustl(
cp_to_string(donor_state%at_index)))//
'_'//trim(domo)// &
2662 '_'//trim(excite)//
'_idx'//trim(adjustl(
cp_to_string(ex_state_idx)))
2664 extension=
".wfn", file_status=
"REPLACE", &
2665 file_action=
"WRITE", file_form=
"UNFORMATTED", &
2666 middle_name=xas_mittle)
2669 qs_kind_set=qs_kind_set, ires=output_unit)
2684 IF (.NOT.
ASSOCIATED(xas_tdp_env%matrix_shalf) .AND. do_pdos)
THEN
2686 nrow_global=nao, ncol_global=nao)
2687 ALLOCATE (xas_tdp_env%matrix_shalf)
2692 CALL cp_fm_power(xas_tdp_env%matrix_shalf, work_fm, 0.5_dp, epsilon(0.0_dp), n_dependent)
2700 IF (output_unit > 0)
THEN
2701 WRITE (unit=output_unit, fmt=
"(/,T5,A,/,T5,A,/,T5,A)") &
2702 "Computing the PDOS of linear-response orbitals for spectral features analysis", &
2703 "Note: using standard PDOS routines => ignore mentions of KS states and MO ", &
2704 " occupation numbers. Eigenvalues in *.pdos files are excitations energies."
2709 IF (nlumo /= 0)
THEN
2710 cpwarn(
"NLUMO is irrelevant for XAS_TDP PDOS. It was overwritten to 0.")
2721 ncubes = bounds(2) - bounds(1) + 1
2722 IF (ncubes > 0)
THEN
2723 ALLOCATE (state_list(ncubes))
2725 state_list(ic) = bounds(1) + ic - 1
2729 IF (.NOT.
ASSOCIATED(state_list))
THEN
2736 IF (
ASSOCIATED(
list))
THEN
2738 DO ic = 1,
SIZE(
list)
2739 state_list(ncubes + ic) =
list(ic)
2741 ncubes = ncubes +
SIZE(
list)
2746 IF (.NOT.
ASSOCIATED(state_list))
THEN
2748 ALLOCATE (state_list(1))
2754 IF (append_cube) pos =
"APPEND"
2756 ALLOCATE (centers(6, ncubes))
2762 DO ido_mo = 1, ndo_mo
2763 DO ispin = 1, nspins
2767 CALL allocate_mo_set(mo_set, nao=nao, nmo=nmo, nelectron=nmo, n_el_f=real(nmo,
dp), &
2768 maxocc=1.0_dp, flexible_electron_count=0.0_dp)
2769 CALL init_mo_set(mo_set, fm_ref=mo_coeff, name=
"PDOS XAS_TDP MOs")
2770 mo_set%eigenvalues(:) = lr_evals(:)
2773 IF (nspins == 1 .AND. ndo_mo == 1)
THEN
2778 nrow=nao, ncol=1, s_firstrow=1, &
2779 s_firstcol=(imo - 1)*ndo_so + (ispin - 1)*ndo_mo + ido_mo, &
2780 t_firstrow=1, t_firstcol=imo)
2787 xas_mittle =
'xasat'//trim(adjustl(
cp_to_string(donor_state%at_index)))//
'_'// &
2788 trim(domon)//
'_'//trim(excite)
2792 qs_env, xas_tdp_section, ispin, xas_mittle, &
2793 external_matrix_shalf=xas_tdp_env%matrix_shalf)
2797 CALL qs_print_cubes(qs_env, mo_set%mo_coeff, ncubes, state_list, centers, &
2798 print_key=print_key, root=xas_mittle, ispin=ispin, &
2812 IF (do_cubes)
DEALLOCATE (centers, state_list)
2814 CALL timestop(handle)
2816 END SUBROUTINE xas_tdp_post
2826 SUBROUTINE make_lumo_guess(xas_tdp_env, xas_tdp_control, qs_env)
2828 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2829 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2830 TYPE(qs_environment_type),
POINTER :: qs_env
2832 CHARACTER(len=*),
PARAMETER :: routinen =
'make_lumo_guess'
2834 INTEGER :: handle, ispin, nao, nelec_spin(2), &
2835 nlumo(2), nocc(2), nspins
2837 REAL(dp),
ALLOCATABLE,
DIMENSION(:) :: evals
2838 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
2839 TYPE(cp_fm_struct_type),
POINTER :: fm_struct, lumo_struct
2840 TYPE(cp_fm_type) :: amatrix, bmatrix, evecs, work_fm
2841 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_ks, matrix_s
2842 TYPE(mp_para_env_type),
POINTER :: para_env
2844 NULLIFY (matrix_ks, matrix_s, para_env, blacs_env)
2845 NULLIFY (lumo_struct, fm_struct)
2847 CALL timeset(routinen, handle)
2849 do_os = xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks
2850 nspins = 1;
IF (do_os) nspins = 2
2851 ALLOCATE (xas_tdp_env%lumo_evecs(nspins))
2852 ALLOCATE (xas_tdp_env%lumo_evals(nspins))
2853 CALL get_qs_env(qs_env, matrix_ks=matrix_ks, matrix_s=matrix_s, nelectron_spin=nelec_spin, &
2854 para_env=para_env, blacs_env=blacs_env)
2855 CALL dbcsr_get_info(matrix_s(1)%matrix, nfullrows_total=nao)
2858 nlumo = nao - nelec_spin
2861 nlumo = nao - nelec_spin(1)/2
2862 nocc = nelec_spin(1)/2
2865 ALLOCATE (xas_tdp_env%ot_prec(nspins))
2867 DO ispin = 1, nspins
2870 CALL cp_fm_struct_create(fm_struct, para_env=para_env, context=blacs_env, &
2871 nrow_global=nao, ncol_global=nao)
2872 CALL cp_fm_create(amatrix, fm_struct)
2873 CALL cp_fm_create(bmatrix, fm_struct)
2874 CALL cp_fm_create(evecs, fm_struct)
2875 CALL cp_fm_create(work_fm, fm_struct)
2876 ALLOCATE (evals(nao))
2877 ALLOCATE (xas_tdp_env%lumo_evals(ispin)%array(nlumo(ispin)))
2879 CALL copy_dbcsr_to_fm(matrix_ks(ispin)%matrix, amatrix)
2880 CALL copy_dbcsr_to_fm(matrix_s(1)%matrix, bmatrix)
2883 CALL cp_fm_geeig(amatrix, bmatrix, evecs, evals, work_fm)
2886 CALL cp_fm_struct_create(lumo_struct, para_env=para_env, context=blacs_env, &
2887 nrow_global=nao, ncol_global=nlumo(ispin))
2888 CALL cp_fm_create(xas_tdp_env%lumo_evecs(ispin), lumo_struct)
2890 CALL cp_fm_to_fm_submat(evecs, xas_tdp_env%lumo_evecs(ispin), nrow=nao, &
2891 ncol=nlumo(ispin), s_firstrow=1, s_firstcol=nocc(ispin) + 1, &
2892 t_firstrow=1, t_firstcol=1)
2894 xas_tdp_env%lumo_evals(ispin)%array(1:nlumo(ispin)) = evals(nocc(ispin) + 1:nao)
2896 CALL build_ot_spin_prec(evecs, evals, ispin, xas_tdp_env, xas_tdp_control, qs_env)
2899 CALL cp_fm_release(amatrix)
2900 CALL cp_fm_release(bmatrix)
2901 CALL cp_fm_release(evecs)
2902 CALL cp_fm_release(work_fm)
2903 CALL cp_fm_struct_release(fm_struct)
2904 CALL cp_fm_struct_release(lumo_struct)
2908 CALL timestop(handle)
2910 END SUBROUTINE make_lumo_guess
2923 SUBROUTINE build_ot_spin_prec(evecs, evals, ispin, xas_tdp_env, xas_tdp_control, qs_env)
2925 TYPE(cp_fm_type),
INTENT(IN) :: evecs
2926 REAL(dp),
DIMENSION(:) :: evals
2928 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2929 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2930 TYPE(qs_environment_type),
POINTER :: qs_env
2932 CHARACTER(len=*),
PARAMETER :: routinen =
'build_ot_spin_prec'
2934 INTEGER :: handle, nao, nelec_spin(2), nguess, &
2938 REAL(dp),
ALLOCATABLE,
DIMENSION(:) :: scaling
2939 TYPE(cp_fm_struct_type),
POINTER :: fm_struct
2940 TYPE(cp_fm_type) :: fm_prec, work_fm
2941 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_s
2942 TYPE(mp_para_env_type),
POINTER :: para_env
2944 NULLIFY (fm_struct, para_env, matrix_s)
2946 CALL timeset(routinen, handle)
2948 do_os = xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks
2949 CALL get_qs_env(qs_env, para_env=para_env, nelectron_spin=nelec_spin, matrix_s=matrix_s)
2950 CALL cp_fm_get_info(evecs, nrow_global=nao, matrix_struct=fm_struct)
2951 CALL cp_fm_create(fm_prec, fm_struct)
2952 ALLOCATE (scaling(nao))
2953 nocc = nelec_spin(1)/2
2956 nocc = nelec_spin(ispin)
2962 IF (xas_tdp_control%n_excited > 0 .AND. xas_tdp_control%n_excited < nguess)
THEN
2963 nguess = xas_tdp_control%n_excited/nspins
2964 ELSE IF (xas_tdp_control%e_range > 0.0_dp)
THEN
2965 nguess = count(evals(nocc + 1:nao) - evals(nocc + 1) <= xas_tdp_control%e_range)
2969 scaling(nocc + 1:nocc + nguess) = 100.0_dp
2971 shift = evals(nocc + 1) - 0.01_dp
2972 scaling(nocc + nguess:nao) = 1.0_dp/(evals(nocc + nguess:nao) - shift)
2974 scaling(1:nocc) = 1.0_dp
2977 CALL cp_fm_create(work_fm, fm_struct)
2979 CALL cp_fm_copy_general(evecs, work_fm, para_env)
2980 CALL cp_fm_column_scale(work_fm, scaling)
2982 CALL parallel_gemm(
'N',
'T', nao, nao, nao, 1.0_dp, work_fm, evecs, 0.0_dp, fm_prec)
2985 ALLOCATE (xas_tdp_env%ot_prec(ispin)%matrix)
2986 CALL dbcsr_create(xas_tdp_env%ot_prec(ispin)%matrix, template=matrix_s(1)%matrix, name=
"OT_PREC")
2987 CALL copy_fm_to_dbcsr(fm_prec, xas_tdp_env%ot_prec(ispin)%matrix)
2988 CALL dbcsr_filter(xas_tdp_env%ot_prec(ispin)%matrix, xas_tdp_control%eps_filter)
2990 CALL cp_fm_release(work_fm)
2991 CALL cp_fm_release(fm_prec)
2993 CALL timestop(handle)
2995 END SUBROUTINE build_ot_spin_prec
3004 SUBROUTINE print_xps(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
3006 TYPE(donor_state_type),
POINTER :: donor_state
3007 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
3008 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
3009 TYPE(qs_environment_type),
POINTER :: qs_env
3011 INTEGER :: ido_mo, ispin, nspins, output_unit
3012 REAL(dp),
ALLOCATABLE,
DIMENSION(:, :) :: ips, soc_shifts
3014 output_unit = cp_logger_get_default_io_unit()
3016 nspins = 1;
IF (xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks) nspins = 2
3018 ALLOCATE (ips(
SIZE(donor_state%gw2x_evals, 1),
SIZE(donor_state%gw2x_evals, 2)))
3019 ips(:, :) = donor_state%gw2x_evals(:, :)
3022 IF (.NOT. xas_tdp_control%is_periodic)
THEN
3025 IF (donor_state%ndo_mo > 1)
THEN
3026 CALL get_soc_splitting(soc_shifts, donor_state, xas_tdp_env, xas_tdp_control, qs_env)
3027 ips(:, :) = ips(:, :) + soc_shifts
3029 IF (output_unit > 0)
THEN
3030 WRITE (output_unit, fmt=
"(/,T5,A,F23.6)") &
3031 "Ionization potentials for XPS (GW2X + SOC): ", -ips(1, 1)*evolt
3033 DO ispin = 1, nspins
3034 DO ido_mo = 1, donor_state%ndo_mo
3036 IF (ispin == 1 .AND. ido_mo == 1) cycle
3038 WRITE (output_unit, fmt=
"(T5,A,F23.6)") &
3039 " ", -ips(ido_mo, ispin)*evolt
3048 IF (output_unit > 0)
THEN
3049 WRITE (output_unit, fmt=
"(/,T5,A,F29.6)") &
3050 "Ionization potentials for XPS (GW2X): ", -ips(1, 1)*evolt
3052 IF (nspins == 2)
THEN
3053 WRITE (output_unit, fmt=
"(T5,A,F29.6)") &
3054 " ", -ips(1, 2)*evolt
3061 END SUBROUTINE print_xps
3070 SUBROUTINE print_xas_tdp_to_file(donor_state, xas_tdp_env, xas_tdp_control, xas_tdp_section)
3072 TYPE(donor_state_type),
POINTER :: donor_state
3073 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
3074 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
3075 TYPE(section_vals_type),
POINTER :: xas_tdp_section
3077 INTEGER :: i, output_unit, xas_tdp_unit
3078 TYPE(cp_logger_type),
POINTER :: logger
3081 logger => cp_get_default_logger()
3083 xas_tdp_unit = cp_print_key_unit_nr(logger, xas_tdp_section,
"PRINT%SPECTRUM", &
3084 extension=
".spectrum", file_position=
"APPEND", &
3085 file_action=
"WRITE", file_form=
"FORMATTED")
3087 output_unit = cp_logger_get_default_io_unit()
3089 IF (output_unit > 0)
THEN
3090 WRITE (output_unit, fmt=
"(/,T5,A,/)") &
3091 "Calculations done: "
3094 IF (xas_tdp_control%do_spin_cons)
THEN
3095 IF (xas_tdp_unit > 0)
THEN
3098 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3099 "==================================================================================", &
3100 "XAS TDP open-shell spin-conserving (no SOC) excitations for DONOR STATE: ", &
3101 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3102 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3103 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3104 "=================================================================================="
3108 IF (xas_tdp_control%do_quad)
THEN
3109 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3110 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3111 DO i = 1,
SIZE(donor_state%sc_evals)
3112 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3113 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4), &
3114 donor_state%quad_osc_str(i)
3116 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3117 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3118 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3119 DO i = 1,
SIZE(donor_state%sc_evals)
3120 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3121 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4), &
3122 donor_state%osc_str(i, 1), donor_state%osc_str(i, 2), donor_state%osc_str(i, 3)
3124 ELSE IF (xas_tdp_control%spin_dip)
THEN
3125 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3126 " Index Excitation energy (eV) fosc dipole (a.u.) alpha-comp beta-comp"
3127 DO i = 1,
SIZE(donor_state%sc_evals)
3128 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6)") &
3129 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4), &
3130 donor_state%alpha_osc(i, 4), donor_state%beta_osc(i, 4)
3133 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3134 " Index Excitation energy (eV) fosc dipole (a.u.)"
3135 DO i = 1,
SIZE(donor_state%sc_evals)
3136 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3137 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4)
3141 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3144 IF (output_unit > 0)
THEN
3145 WRITE (output_unit, fmt=
"(T5,A,F17.6)") &
3146 "First spin-conserving XAS excitation energy (eV): ", donor_state%sc_evals(1)*evolt
3151 IF (xas_tdp_control%do_spin_flip)
THEN
3152 IF (xas_tdp_unit > 0)
THEN
3155 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3156 "==================================================================================", &
3157 "XAS TDP open-shell spin-flip (no SOC) excitations for DONOR STATE: ", &
3158 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3159 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3160 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3161 "=================================================================================="
3165 IF (xas_tdp_control%do_quad)
THEN
3166 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3167 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3168 DO i = 1,
SIZE(donor_state%sf_evals)
3169 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3170 i, donor_state%sf_evals(i)*evolt, 0.0_dp, 0.0_dp
3172 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3173 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3174 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3175 DO i = 1,
SIZE(donor_state%sf_evals)
3176 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3177 i, donor_state%sf_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp
3179 ELSE IF (xas_tdp_control%spin_dip)
THEN
3180 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3181 " Index Excitation energy (eV) fosc dipole (a.u.) alpha-comp beta-comp"
3182 DO i = 1,
SIZE(donor_state%sf_evals)
3183 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6)") &
3184 i, donor_state%sf_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp
3187 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3188 " Index Excitation energy (eV) fosc dipole (a.u.)"
3189 DO i = 1,
SIZE(donor_state%sf_evals)
3190 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3191 i, donor_state%sf_evals(i)*evolt, 0.0_dp
3195 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3198 IF (output_unit > 0)
THEN
3199 WRITE (output_unit, fmt=
"(T5,A,F23.6)") &
3200 "First spin-flip XAS excitation energy (eV): ", donor_state%sf_evals(1)*evolt
3204 IF (xas_tdp_control%do_singlet)
THEN
3205 IF (xas_tdp_unit > 0)
THEN
3208 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3209 "==================================================================================", &
3210 "XAS TDP singlet excitations (no SOC) for DONOR STATE: ", &
3211 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3212 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3213 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3214 "=================================================================================="
3218 IF (xas_tdp_control%do_quad)
THEN
3219 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3220 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3221 DO i = 1,
SIZE(donor_state%sg_evals)
3222 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3223 i, donor_state%sg_evals(i)*evolt, donor_state%osc_str(i, 4), &
3224 donor_state%quad_osc_str(i)
3226 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3227 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3228 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3229 DO i = 1,
SIZE(donor_state%sg_evals)
3230 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3231 i, donor_state%sg_evals(i)*evolt, donor_state%osc_str(i, 4), &
3232 donor_state%osc_str(i, 1), donor_state%osc_str(i, 2), donor_state%osc_str(i, 3)
3235 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3236 " Index Excitation energy (eV) fosc dipole (a.u.)"
3237 DO i = 1,
SIZE(donor_state%sg_evals)
3238 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3239 i, donor_state%sg_evals(i)*evolt, donor_state%osc_str(i, 4)
3243 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3246 IF (output_unit > 0)
THEN
3247 WRITE (output_unit, fmt=
"(T5,A,F25.6)") &
3248 "First singlet XAS excitation energy (eV): ", donor_state%sg_evals(1)*evolt
3252 IF (xas_tdp_control%do_triplet)
THEN
3253 IF (xas_tdp_unit > 0)
THEN
3256 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3257 "==================================================================================", &
3258 "XAS TDP triplet excitations (no SOC) for DONOR STATE: ", &
3259 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3260 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3261 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3262 "=================================================================================="
3266 IF (xas_tdp_control%do_quad)
THEN
3267 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3268 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3269 DO i = 1,
SIZE(donor_state%tp_evals)
3270 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3271 i, donor_state%tp_evals(i)*evolt, 0.0_dp, 0.0_dp
3273 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3274 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3275 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3276 DO i = 1,
SIZE(donor_state%tp_evals)
3277 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3278 i, donor_state%tp_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp
3280 ELSE IF (xas_tdp_control%spin_dip)
THEN
3281 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3282 " Index Excitation energy (eV) fosc dipole (a.u.) alpha-comp beta-comp"
3283 DO i = 1,
SIZE(donor_state%tp_evals)
3284 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6)") &
3285 i, donor_state%tp_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp
3288 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3289 " Index Excitation energy (eV) fosc dipole (a.u.)"
3290 DO i = 1,
SIZE(donor_state%tp_evals)
3291 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3292 i, donor_state%tp_evals(i)*evolt, 0.0_dp
3296 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3299 IF (output_unit > 0)
THEN
3300 WRITE (output_unit, fmt=
"(T5,A,F25.6)") &
3301 "First triplet XAS excitation energy (eV): ", donor_state%tp_evals(1)*evolt
3305 IF (xas_tdp_control%do_soc .AND. donor_state%state_type == xas_2p_type)
THEN
3306 IF (xas_tdp_unit > 0)
THEN
3309 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3310 "==================================================================================", &
3311 "XAS TDP excitations after spin-orbit coupling for DONOR STATE: ", &
3312 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3313 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3314 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3315 "=================================================================================="
3318 IF (xas_tdp_control%do_quad)
THEN
3319 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3320 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3321 DO i = 1,
SIZE(donor_state%soc_evals)
3322 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3323 i, donor_state%soc_evals(i)*evolt, donor_state%soc_osc_str(i, 4), &
3324 donor_state%soc_quad_osc_str(i)
3326 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3327 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3328 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3329 DO i = 1,
SIZE(donor_state%soc_evals)
3330 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3331 i, donor_state%soc_evals(i)*evolt, donor_state%soc_osc_str(i, 4), &
3332 donor_state%soc_osc_str(i, 1), donor_state%soc_osc_str(i, 2), donor_state%soc_osc_str(i, 3)
3335 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3336 " Index Excitation energy (eV) fosc dipole (a.u.)"
3337 DO i = 1,
SIZE(donor_state%soc_evals)
3338 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3339 i, donor_state%soc_evals(i)*evolt, donor_state%soc_osc_str(i, 4)
3343 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3346 IF (output_unit > 0)
THEN
3347 WRITE (output_unit, fmt=
"(T5,A,F29.6)") &
3348 "First SOC XAS excitation energy (eV): ", donor_state%soc_evals(1)*evolt
3352 CALL cp_print_key_finished_output(xas_tdp_unit, logger, xas_tdp_section,
"PRINT%SPECTRUM")
3354 END SUBROUTINE print_xas_tdp_to_file
3364 SUBROUTINE write_donor_state_restart(ex_type, donor_state, xas_tdp_section, qs_env)
3366 INTEGER,
INTENT(IN) :: ex_type
3367 TYPE(donor_state_type),
POINTER :: donor_state
3368 TYPE(section_vals_type),
POINTER :: xas_tdp_section
3369 TYPE(qs_environment_type),
POINTER :: qs_env
3371 CHARACTER(len=*),
PARAMETER :: routinen =
'write_donor_state_restart'
3373 CHARACTER(len=default_path_length) :: filename
3374 CHARACTER(len=default_string_length) :: domo, excite, my_middle
3375 INTEGER :: ex_atom, handle, ispin, nao, ndo_mo, &
3376 nex, nspins, output_unit, rst_unit, &
3378 INTEGER,
DIMENSION(:, :),
POINTER :: mo_indices
3380 REAL(dp),
DIMENSION(:),
POINTER :: lr_evals
3381 TYPE(cp_fm_type),
POINTER :: lr_coeffs
3382 TYPE(cp_logger_type),
POINTER :: logger
3383 TYPE(mo_set_type),
DIMENSION(:),
POINTER :: mos
3384 TYPE(section_vals_type),
POINTER :: print_key
3386 NULLIFY (logger, lr_coeffs, lr_evals, print_key, mos)
3389 logger => cp_get_default_logger()
3391 IF (btest(cp_print_key_should_output(logger%iter_info, xas_tdp_section, &
3392 "PRINT%RESTART", used_print_key=print_key), cp_p_file)) do_print = .true.
3394 IF (.NOT. do_print)
RETURN
3396 CALL timeset(routinen, handle)
3398 output_unit = cp_logger_get_default_io_unit()
3401 SELECT CASE (ex_type)
3402 CASE (tddfpt_spin_cons)
3403 lr_evals => donor_state%sc_evals
3404 lr_coeffs => donor_state%sc_coeffs
3407 CASE (tddfpt_spin_flip)
3408 lr_evals => donor_state%sf_evals
3409 lr_coeffs => donor_state%sf_coeffs
3412 CASE (tddfpt_singlet)
3413 lr_evals => donor_state%sg_evals
3414 lr_coeffs => donor_state%sg_coeffs
3417 CASE (tddfpt_triplet)
3418 lr_evals => donor_state%tp_evals
3419 lr_coeffs => donor_state%tp_coeffs
3424 SELECT CASE (donor_state%state_type)
3433 ndo_mo = donor_state%ndo_mo
3434 nex =
SIZE(lr_evals)
3435 CALL cp_fm_get_info(lr_coeffs, nrow_global=nao)
3436 state_type = donor_state%state_type
3437 ex_atom = donor_state%at_index
3438 mo_indices => donor_state%mo_indices
3442 my_middle =
'xasat'//trim(adjustl(cp_to_string(ex_atom)))//
'_'//trim(domo)//
'_'//trim(excite)
3443 rst_unit = cp_print_key_unit_nr(logger, xas_tdp_section,
"PRINT%RESTART", extension=
".rst", &
3444 file_status=
"REPLACE", file_action=
"WRITE", &
3445 file_form=
"UNFORMATTED", middle_name=trim(my_middle))
3447 filename = cp_print_key_generate_filename(logger, print_key, middle_name=trim(my_middle), &
3448 extension=
".rst", my_local=.false.)
3450 IF (output_unit > 0)
THEN
3451 WRITE (unit=output_unit, fmt=
"(/,T5,A,/T5,A,A,A)") &
3452 "Linear-response orbitals and excitation energies are written in: ", &
3453 '"', trim(filename),
'"'
3457 IF (rst_unit > 0)
THEN
3458 WRITE (rst_unit) ex_atom, state_type, ndo_mo, ex_type
3459 WRITE (rst_unit) nao, nex, nspins
3460 WRITE (rst_unit) mo_indices(:, :)
3461 WRITE (rst_unit) lr_evals(:)
3463 CALL cp_fm_write_unformatted(lr_coeffs, rst_unit)
3466 CALL get_qs_env(qs_env, mos=mos)
3467 DO ispin = 1, nspins
3468 CALL cp_fm_write_unformatted(mos(ispin)%mo_coeff, rst_unit)
3472 CALL cp_print_key_finished_output(rst_unit, logger, xas_tdp_section,
"PRINT%RESTART")
3474 CALL timestop(handle)
3476 END SUBROUTINE write_donor_state_restart
3485 SUBROUTINE read_donor_state_restart(donor_state, ex_type, filename, qs_env)
3487 TYPE(donor_state_type),
POINTER :: donor_state
3488 INTEGER,
INTENT(OUT) :: ex_type
3489 CHARACTER(len=*),
INTENT(IN) :: filename
3490 TYPE(qs_environment_type),
POINTER :: qs_env
3492 CHARACTER(len=*),
PARAMETER :: routinen =
'read_donor_state_restart'
3494 INTEGER :: handle, ispin, nao, nex, nspins, &
3495 output_unit, read_params(7), rst_unit
3496 INTEGER,
DIMENSION(:, :),
POINTER :: mo_indices
3497 LOGICAL :: file_exists
3498 REAL(dp),
DIMENSION(:),
POINTER :: lr_evals
3499 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
3500 TYPE(cp_fm_struct_type),
POINTER :: fm_struct
3501 TYPE(cp_fm_type),
POINTER :: lr_coeffs
3502 TYPE(mo_set_type),
DIMENSION(:),
POINTER :: mos
3503 TYPE(mp_comm_type) :: group
3504 TYPE(mp_para_env_type),
POINTER :: para_env
3506 NULLIFY (lr_evals, lr_coeffs, para_env, fm_struct, blacs_env, mos)
3508 CALL timeset(routinen, handle)
3510 output_unit = cp_logger_get_default_io_unit()
3511 cpassert(
ASSOCIATED(donor_state))
3512 CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
3515 file_exists = .false.
3518 IF (para_env%is_source())
THEN
3520 INQUIRE (file=filename, exist=file_exists)
3521 IF (.NOT. file_exists) cpabort(
"Trying to read non-existing XAS_TDP restart file")
3523 CALL open_file(file_name=trim(filename), file_action=
"READ", file_form=
"UNFORMATTED", &
3524 file_position=
"REWIND", file_status=
"OLD", unit_number=rst_unit)
3527 IF (output_unit > 0)
THEN
3528 WRITE (unit=output_unit, fmt=
"(/,T5,A,/,T5,A,A,A)") &
3529 "Reading linear-response orbitals and excitation energies from file: ", &
3534 IF (rst_unit > 0)
THEN
3535 READ (rst_unit) read_params(1:4)
3536 READ (rst_unit) read_params(5:7)
3538 CALL group%bcast(read_params)
3539 donor_state%at_index = read_params(1)
3540 donor_state%state_type = read_params(2)
3541 donor_state%ndo_mo = read_params(3)
3542 ex_type = read_params(4)
3543 nao = read_params(5)
3544 nex = read_params(6)
3545 nspins = read_params(7)
3547 ALLOCATE (mo_indices(donor_state%ndo_mo, nspins))
3548 IF (rst_unit > 0)
THEN
3549 READ (rst_unit) mo_indices(1:donor_state%ndo_mo, 1:nspins)
3551 CALL group%bcast(mo_indices)
3552 donor_state%mo_indices => mo_indices
3555 ALLOCATE (lr_evals(nex))
3556 IF (rst_unit > 0)
READ (rst_unit) lr_evals(1:nex)
3557 CALL group%bcast(lr_evals)
3560 CALL cp_fm_struct_create(fm_struct, context=blacs_env, para_env=para_env, &
3561 nrow_global=nao, ncol_global=nex*donor_state%ndo_mo*nspins)
3562 ALLOCATE (lr_coeffs)
3563 CALL cp_fm_create(lr_coeffs, fm_struct)
3564 CALL cp_fm_read_unformatted(lr_coeffs, rst_unit)
3565 CALL cp_fm_struct_release(fm_struct)
3568 CALL get_qs_env(qs_env, mos=mos)
3569 DO ispin = 1, nspins
3570 CALL cp_fm_read_unformatted(mos(ispin)%mo_coeff, rst_unit)
3574 IF (para_env%is_source())
THEN
3575 CALL close_file(unit_number=rst_unit)
3579 SELECT CASE (ex_type)
3580 CASE (tddfpt_spin_cons)
3581 donor_state%sc_evals => lr_evals
3582 donor_state%sc_coeffs => lr_coeffs
3583 CASE (tddfpt_spin_flip)
3584 donor_state%sf_evals => lr_evals
3585 donor_state%sf_coeffs => lr_coeffs
3586 CASE (tddfpt_singlet)
3587 donor_state%sg_evals => lr_evals
3588 donor_state%sg_coeffs => lr_coeffs
3589 CASE (tddfpt_triplet)
3590 donor_state%tp_evals => lr_evals
3591 donor_state%tp_coeffs => lr_coeffs
3594 CALL timestop(handle)
3596 END SUBROUTINE read_donor_state_restart
3604 SUBROUTINE restart_calculation(rst_filename, xas_tdp_section, qs_env)
3606 CHARACTER(len=*),
INTENT(IN) :: rst_filename
3607 TYPE(section_vals_type),
POINTER :: xas_tdp_section
3608 TYPE(qs_environment_type),
POINTER :: qs_env
3611 TYPE(donor_state_type),
POINTER :: donor_state
3612 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
3614 NULLIFY (xas_tdp_env, donor_state)
3617 ALLOCATE (donor_state)
3618 CALL donor_state_create(donor_state)
3619 CALL read_donor_state_restart(donor_state, ex_type, rst_filename, qs_env)
3622 CALL xas_tdp_env_create(xas_tdp_env)
3623 CALL xas_tdp_post(ex_type, donor_state, xas_tdp_env, xas_tdp_section, qs_env)
3626 CALL xas_tdp_env_release(xas_tdp_env)
3627 CALL free_ds_memory(donor_state)
3628 DEALLOCATE (donor_state%mo_indices)
3629 DEALLOCATE (donor_state)
3631 END SUBROUTINE restart_calculation
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
Types and set/get functions for auxiliary density matrix methods.
Contains methods used in the context of density fitting.
subroutine, public admm_uncorrect_for_eigenvalues(ispin, admm_env, ks_matrix)
...
subroutine, public admm_correct_for_eigenvalues(ispin, admm_env, ks_matrix)
...
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
subroutine, public get_gto_basis_set(gto_basis_set, name, aliases, norm_type, kind_radius, ncgf, nset, nsgf, cgf_symbol, sgf_symbol, norm_cgf, set_radius, lmax, lmin, lx, ly, lz, m, ncgf_set, npgf, nsgf_set, nshell, cphi, pgf_radius, sphi, scon, zet, first_cgf, first_sgf, l, last_cgf, last_sgf, n, gcc, maxco, maxl, maxpgf, maxsgf_set, maxshell, maxso, nco_sum, npgf_sum, nshell_sum, maxder, short_kind_radius, npgf_seg_sum, ccon)
...
subroutine, public 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.
subroutine, public dbcsr_reserve_all_blocks(matrix)
Reserves all blocks.
DBCSR operations in CP2K.
subroutine, public cp_dbcsr_sm_fm_multiply(matrix, fm_in, fm_out, ncol, alpha, beta)
multiply a dbcsr with a fm matrix
subroutine, public copy_dbcsr_to_fm(matrix, fm)
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. Use cuSOLVERMp directly when requested and large enough; otherwi...
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
subroutine, public cp_fm_copy_general(source, destination, para_env)
General copy of a fm matrix to another fm matrix. Uses non-blocking MPI rather than ScaLAPACK.
subroutine, public cp_fm_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_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
creates a new full matrix with the given structure
subroutine, public cp_fm_get_submatrix(fm, target_m, start_row, start_col, n_rows, n_cols, transpose)
gets a submatrix of a full matrix op(target_m)(1:n_rows,1:n_cols) =fm(start_row:start_row+n_rows,...
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer, parameter, public debug_print_level
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, ncgf)
Get the components of a particle set.
Define the data structure for the particle information.
Periodic Table related data definitions.
type(atom), dimension(0:nelem), public ptable
Definition of physical constants:
real(kind=dp), parameter, public a_fine
real(kind=dp), parameter, public evolt
real(kind=dp), parameter, public angstrom
collects routines that calculate density matrices
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Calculate the interaction radii for the operator matrix calculation.
subroutine, public init_interaction_radii_orb_basis(orb_basis_set, eps_pgf_orb, eps_pgf_short)
...
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, cneo_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, u_of_dft_plus_u, j_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, j0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, init_u_ramping_each_scf, reltmat, ghost, monovalent, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
Driver for the localization that should be general for all the methods available and all the definiti...
subroutine, public qs_loc_driver(qs_env, qs_loc_env, print_loc_section, myspin, ext_mo_coeff)
set up the calculation of localized orbitals
Driver for the localization that should be general for all the methods available and all the definiti...
subroutine, public qs_print_cubes(qs_env, mo_coeff, nstates, state_list, centers, print_key, root, ispin, idir, state0, file_position)
write the cube files for a set of selected states
subroutine, public centers_spreads_berry(qs_loc_env, nmoloc, cell, weights, ispin, print_loc_section, zij, c_zij, only_initial_out)
...
New version of the module for the localization of the molecular orbitals This should be able to use d...
subroutine, public localized_wfn_control_create(localized_wfn_control)
create the localized_wfn_control_type
subroutine, public qs_loc_env_release(qs_loc_env)
...
subroutine, public get_qs_loc_env(qs_loc_env, cell, local_molecules, localized_wfn_control, moloc_coeff, op_sm_set, op_fm_set, para_env, particle_set, weights, dim_op)
...
subroutine, public qs_loc_env_create(qs_loc_env)
...
Some utilities for the construction of the localization environment.
subroutine, public qs_loc_env_init(qs_loc_env, localized_wfn_control, qs_env, myspin, do_localize, loc_coeff, mo_loc_history)
allocates the data, and initializes the operators
subroutine, public set_loc_centers(localized_wfn_control, nmoloc, nspins)
create the center and spread array and the file names for the output
subroutine, public qs_loc_control_init(qs_loc_env, loc_section, do_homo, do_mixed, do_xas, nloc_xas, spin_xas)
initializes everything needed for localization of the HOMOs
Definition and initialisation of the mo data type.
subroutine, public write_mo_set_low(mo_array, qs_kind_set, particle_set, ires, rt_mos, matrix_ks)
...
collects routines that perform operations directly related to MOs
Definition and initialisation of the mo data type.
subroutine, public duplicate_mo_set(mo_set_new, mo_set_old)
allocate a new mo_set, and copy the old data
subroutine, public init_mo_set(mo_set, fm_pool, fm_ref, fm_struct, name, counter)
initializes an allocated mo_set. eigenvalues, mo_coeff, occupation_numbers are valid only after this ...
subroutine, public allocate_mo_set(mo_set, nao, nmo, nelectron, n_el_f, maxocc, flexible_electron_count)
Allocates a mo set and partially initializes it (nao,nmo,nelectron, and flexible_electron_count are v...
subroutine, public deallocate_mo_set(mo_set)
Deallocate a wavefunction data structure.
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kts, mu, flexible_electron_count)
Get the components of a MO set data structure.
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, unoccupied_orbs, unoccupied_evals, pdos_print_key, write_pdos, write_pdos_raw)
Compute and write projected density of states.
module that contains the definitions of the scf types
integer, parameter, public ot_method_nr
Define Resonant Inelastic XRAY Scattering (RIXS) control type and associated create,...
All kind of helpful little routines.
pure integer function, public locate(array, x)
Purpose: Given an array array(1:n), and given a value x, a value x_index is returned which is the ind...
pure integer function, dimension(2), public get_limit(m, n, me)
divide m entries into n parts, return size of part me
driver for the xas calculation and xas_scf for the tp method
subroutine, public calc_stogto_overlap(base_a, base_b, matrix)
...
This module deals with all the integrals done on local atomic grids in xas_tdp. This is mostly used t...
subroutine, public init_xas_atom_env(xas_atom_env, xas_tdp_env, xas_tdp_control, qs_env, ltddfpt)
Initializes a xas_atom_env type given the qs_enxas_atom_env, qs_envv.
subroutine, public integrate_soc_atoms(matrix_soc, xas_atom_env, qs_env, soc_atom_env)
Computes the SOC matrix elements with respect to the ORB basis set for each atomic kind and put them ...
subroutine, public integrate_fxc_atoms(int_fxc, xas_atom_env, xas_tdp_control, qs_env)
Integrate the xc kernel as a function of r on the atomic grids for the RI_XAS basis.
Second order perturbation correction to XAS_TDP spectra (i.e. shift)
subroutine, public gw2x_shift(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
Computes the ionization potential using the GW2X method of Shigeta et. al. The result cam be used for...
subroutine, public get_soc_splitting(soc_shifts, donor_state, xas_tdp_env, xas_tdp_control, qs_env)
We try to compute the spin-orbit splitting via perturbation theory. We keep it \ cheap by only inculd...
3-center integrals machinery for the XAS_TDP method
subroutine, public compute_ri_coulomb2_int(ex_kind, xas_tdp_env, xas_tdp_control, qs_env)
Computes the two-center Coulomb integral needed for the RI in kernel calculation. Stores the integral...
subroutine, public compute_ri_3c_coulomb(xas_tdp_env, qs_env)
Computes the RI Coulomb 3-center integrals (ab|c), where c is from the RI_XAS basis and centered on t...
subroutine, public compute_ri_exchange2_int(ex_kind, xas_tdp_env, xas_tdp_control, qs_env)
Computes the two-center Exchange integral needed for the RI in kernel calculation....
subroutine, public compute_ri_3c_exchange(ex_atoms, xas_tdp_env, xas_tdp_control, qs_env)
Computes the RI exchange 3-center integrals (ab|c), where c is from the RI_XAS basis and centered on ...
Methods for X-Ray absorption spectroscopy (XAS) using TDDFPT.
subroutine, public xas_tdp_init(xas_tdp_env, xas_tdp_control, qs_env, rixs_env)
Overall control and environment types initialization.
subroutine, public xas_tdp(qs_env, rixs_env)
Driver for XAS TDDFT calculations.
Define XAS TDP control type and associated create, release, etc subroutines, as well as XAS TDP envir...
subroutine, public xas_tdp_env_create(xas_tdp_env)
Creates a TDP XAS environment type.
subroutine, public xas_tdp_env_release(xas_tdp_env)
Releases the TDP XAS environment type.
subroutine, public donor_state_create(donor_state)
Creates a donor_state.
subroutine, public xas_tdp_control_release(xas_tdp_control)
Releases the xas_tdp_control_type.
subroutine, public xas_atom_env_create(xas_atom_env)
Creates a xas_atom_env type.
subroutine, public set_xas_tdp_env(xas_tdp_env, nex_atoms, nex_kinds)
Sets values of selected variables within the TDP XAS environment type.
subroutine, public free_ds_memory(donor_state)
Deallocate a donor_state's heavy attributes.
subroutine, public set_donor_state(donor_state, at_index, at_symbol, kind_index, state_type)
sets specified values of the donor state type
subroutine, public xas_tdp_control_create(xas_tdp_control)
Creates and initializes the xas_tdp_control_type.
subroutine, public free_exat_memory(xas_tdp_env, atom, end_of_batch)
Releases the memory heavy attribute of xas_tdp_env that are specific to the current excited atom.
subroutine, public xas_atom_env_release(xas_atom_env)
Releases the xas_atom_env type.
subroutine, public read_xas_tdp_control(xas_tdp_control, xas_tdp_section)
Reads the inputs and stores in xas_tdp_control_type.
Utilities for X-ray absorption spectroscopy using TDDFPT.
subroutine, public include_rcs_soc(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
Includes the SOC effects on the precomputed restricted closed-shell singlet and triplet excitations....
subroutine, public setup_xas_tdp_prob(donor_state, qs_env, xas_tdp_env, xas_tdp_control)
Builds the matrix that defines the XAS TDDFPT generalized eigenvalue problem to be solved for excitat...
subroutine, public solve_xas_tdp_prob(donor_state, xas_tdp_control, xas_tdp_env, qs_env, ex_type)
Solves the XAS TDP generalized eigenvalue problem omega*C = matrix_tdp*C using standard full diagonal...
subroutine, public include_os_soc(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
Includes the SOC effects on the precomputed spin-conserving and spin-flip excitations from an open-sh...
Writes information on XC functionals to output.
subroutine, public xc_write(iounit, xc_section, lsd)
...
stores some data used in wavefunction fitting
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
keeps the information about the structure of a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.
A type that holds controlling information for the calculation of the spread of wfn and the optimizati...
contains all the info needed by quickstep to calculate the spread of a selected set of orbitals and i...
Type containing informations about a single donor state.
a environment type that contains all the info needed for XAS_TDP atomic grid calculations
Type containing control information for TDP XAS calculations.
Type containing informations such as inputs and results for TDP XAS calculations.