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))
THEN
804 xas_tdp_control%n_search = minval(homo)
807 nloc_xas=xas_tdp_control%n_search, spin_xas=1)
811 qs_loc_env%localized_wfn_control%nloc_states(2) = xas_tdp_control%n_search
812 qs_loc_env%localized_wfn_control%lu_bound_states(1, 2) = 1
813 qs_loc_env%localized_wfn_control%lu_bound_states(2, 2) = xas_tdp_control%n_search
817 qs_loc_env%localized_wfn_control%operator_type =
op_loc_berry
818 qs_loc_env%localized_wfn_control%max_iter = 25000
819 IF (.NOT. xas_tdp_control%do_loc)
THEN
820 qs_loc_env%localized_wfn_control%localization_method =
do_loc_none
822 n_moloc = qs_loc_env%localized_wfn_control%nloc_states
823 CALL set_loc_centers(qs_loc_env%localized_wfn_control, n_moloc, nspins)
826 qs_env, do_localize=.true.)
829 qs_env, do_localize=.true., myspin=1)
835 ALLOCATE (xas_tdp_env%mos_of_ex_atoms(xas_tdp_control%n_search, nex_atoms, nspins))
838 IF (do_os) nspins = 2
839 CALL get_qs_env(qs_env, matrix_s=matrix_s, mos=mos)
841 ALLOCATE (xas_tdp_env%q_projector(nspins))
842 ALLOCATE (xas_tdp_env%q_projector(1)%matrix)
843 CALL dbcsr_create(xas_tdp_env%q_projector(1)%matrix, name=
"Q PROJECTOR ALPHA", &
844 template=matrix_s(1)%matrix, matrix_type=dbcsr_type_no_symmetry)
846 ALLOCATE (xas_tdp_env%q_projector(2)%matrix)
847 CALL dbcsr_create(xas_tdp_env%q_projector(2)%matrix, name=
"Q PROJECTOR BETA", &
848 template=matrix_s(1)%matrix, matrix_type=dbcsr_type_no_symmetry)
852 CALL dbcsr_create(matrix_p, name=
"RHO_AO", template=matrix_s(1)%matrix, matrix_type=dbcsr_type_no_symmetry)
856 fact = -0.5_dp;
IF (do_os) fact = -1.0_dp
860 CALL dbcsr_multiply(
'N',
'N', fact, matrix_s(1)%matrix, matrix_p, 0.0_dp, &
861 xas_tdp_env%q_projector(1)%matrix, filter_eps=xas_tdp_control%eps_filter)
868 CALL dbcsr_multiply(
'N',
'N', fact, matrix_s(1)%matrix, matrix_p, 0.0_dp, &
869 xas_tdp_env%q_projector(2)%matrix, filter_eps=xas_tdp_control%eps_filter)
875 DEALLOCATE (matrix_p)
878 ALLOCATE (xas_tdp_env%dipmat(3))
880 ALLOCATE (xas_tdp_env%dipmat(i)%matrix)
881 CALL dbcsr_copy(matrix_tmp, matrix_s(1)%matrix, name=
"XAS TDP dipole matrix")
882 IF (xas_tdp_control%dipole_form ==
xas_dip_vel)
THEN
883 CALL dbcsr_create(xas_tdp_env%dipmat(i)%matrix, template=matrix_s(1)%matrix, &
884 matrix_type=dbcsr_type_antisymmetric)
887 CALL dbcsr_create(xas_tdp_env%dipmat(i)%matrix, template=matrix_s(1)%matrix, &
888 matrix_type=dbcsr_type_symmetric)
889 CALL dbcsr_copy(xas_tdp_env%dipmat(i)%matrix, matrix_tmp)
891 CALL dbcsr_set(xas_tdp_env%dipmat(i)%matrix, 0.0_dp)
896 IF (xas_tdp_control%do_quad)
THEN
897 ALLOCATE (xas_tdp_env%quadmat(6))
899 ALLOCATE (xas_tdp_env%quadmat(i)%matrix)
900 CALL dbcsr_copy(xas_tdp_env%quadmat(i)%matrix, matrix_s(1)%matrix, name=
"XAS TDP quadrupole matrix")
901 CALL dbcsr_set(xas_tdp_env%quadmat(i)%matrix, 0.0_dp)
906 IF (xas_tdp_control%dipole_form ==
xas_dip_vel)
THEN
912 IF (xas_tdp_control%do_soc .OR. xas_tdp_control%do_gw2x)
THEN
913 ALLOCATE (xas_tdp_env%orb_soc(3))
915 ALLOCATE (xas_tdp_env%orb_soc(i)%matrix)
920 CALL safety_check(xas_tdp_control, qs_env)
926 IF (xas_tdp_control%do_ot .OR. xas_tdp_control%do_gw2x)
THEN
927 CALL make_lumo_guess(xas_tdp_env, xas_tdp_control, qs_env)
940 SUBROUTINE get_ri_3c_batches(ex_atoms_of_kind, nbatch, batch_size, atoms_of_kind, xas_tdp_env)
942 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(INOUT) :: ex_atoms_of_kind
943 INTEGER,
INTENT(OUT) :: nbatch
944 INTEGER,
INTENT(IN) :: batch_size
945 INTEGER,
DIMENSION(:),
INTENT(IN) :: atoms_of_kind
948 INTEGER :: iat, iatom, nex_atom
953 DO iat = 1,
SIZE(atoms_of_kind)
954 iatom = atoms_of_kind(iat)
955 IF (.NOT. any(xas_tdp_env%ex_atom_indices == iatom)) cycle
956 nex_atom = nex_atom + 1
959 ALLOCATE (ex_atoms_of_kind(nex_atom))
961 DO iat = 1,
SIZE(atoms_of_kind)
962 iatom = atoms_of_kind(iat)
963 IF (.NOT. any(xas_tdp_env%ex_atom_indices == iatom)) cycle
964 nex_atom = nex_atom + 1
965 ex_atoms_of_kind(nex_atom) = iatom
970 CALL rng_stream%shuffle(ex_atoms_of_kind(1:nex_atom))
972 nbatch = nex_atom/batch_size
973 IF (nbatch*batch_size /= nex_atom) nbatch = nbatch + 1
975 END SUBROUTINE get_ri_3c_batches
982 SUBROUTINE safety_check(xas_tdp_control, qs_env)
990 IF (xas_tdp_control%is_periodic .AND. xas_tdp_control%do_hfx &
992 cpabort(
"XAS TDP with Coulomb operator for exact exchange only supports non-periodic BCs")
996 IF (xas_tdp_control%do_roks .OR. xas_tdp_control%do_uks)
THEN
998 IF (.NOT. (xas_tdp_control%do_spin_cons .OR. xas_tdp_control%do_spin_flip))
THEN
999 cpabort(
"Need spin-conserving and/or spin-flip excitations for open-shell systems")
1002 IF (xas_tdp_control%do_singlet .OR. xas_tdp_control%do_triplet)
THEN
1003 cpabort(
"Singlet/triplet excitations only for restricted closed-shell systems")
1006 IF (xas_tdp_control%do_soc .AND. .NOT. &
1007 (xas_tdp_control%do_spin_flip .AND. xas_tdp_control%do_spin_cons))
THEN
1009 cpabort(
"Both spin-conserving and spin-flip excitations are required for SOC")
1013 IF (.NOT. (xas_tdp_control%do_singlet .OR. xas_tdp_control%do_triplet))
THEN
1014 cpabort(
"Need singlet and/or triplet excitations for closed-shell systems")
1017 IF (xas_tdp_control%do_spin_cons .OR. xas_tdp_control%do_spin_flip)
THEN
1018 cpabort(
"Spin-conserving/spin-flip excitations only for open-shell systems")
1021 IF (xas_tdp_control%do_soc .AND. .NOT. &
1022 (xas_tdp_control%do_singlet .AND. xas_tdp_control%do_triplet))
THEN
1024 cpabort(
"Both singlet and triplet excitations are needed for SOC")
1029 IF (xas_tdp_control%do_soc .AND. xas_tdp_control%e_range > 0.0_dp)
THEN
1030 cpwarn(
"Using E_RANGE and SOC together may lead to crashes, use N_EXCITED for safety.")
1034 IF (.NOT. xas_tdp_control%tamm_dancoff)
THEN
1036 IF (xas_tdp_control%do_spin_flip)
THEN
1037 cpabort(
"Spin-flip kernel only implemented for Tamm-Dancoff approximation")
1040 IF (xas_tdp_control%do_ot)
THEN
1041 cpabort(
"OT diagonalization only available within the Tamm-Dancoff approximation")
1046 IF (xas_tdp_control%do_gw2x)
THEN
1047 IF (.NOT. xas_tdp_control%do_hfx)
THEN
1048 cpabort(
"GW2x requires the definition of the EXACT_EXCHANGE kernel")
1050 IF (.NOT. xas_tdp_control%do_loc)
THEN
1051 cpabort(
"GW2X requires the LOCALIZE keyword in DONOR_STATES")
1056 CALL get_qs_env(qs_env, dft_control=dft_control)
1057 IF (dft_control%do_admm)
THEN
1062 cpabort(
"XAS_TDP only compatible with ADMM purification NONE, CAUCHY_SUBSPACE and MO_DIAG")
1067 END SUBROUTINE safety_check
1075 SUBROUTINE print_info(ou, xas_tdp_control, qs_env)
1077 INTEGER,
INTENT(IN) :: ou
1087 NULLIFY (input, kernel_section, dft_control, matrix_s)
1089 CALL get_qs_env(qs_env, input=input, dft_control=dft_control, matrix_s=matrix_s)
1097 IF (xas_tdp_control%do_uks)
THEN
1098 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1099 "XAS_TDP| Reference calculation: Unrestricted Kohn-Sham"
1100 ELSE IF (xas_tdp_control%do_roks)
THEN
1101 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1102 "XAS_TDP| Reference calculation: Restricted Open-Shell Kohn-Sham"
1104 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1105 "XAS_TDP| Reference calculation: Restricted Closed-Shell Kohn-Sham"
1109 IF (xas_tdp_control%tamm_dancoff)
THEN
1110 WRITE (unit=ou, fmt=
"(T3,A)") &
1111 "XAS_TDP| Tamm-Dancoff Approximation (TDA): On"
1113 WRITE (unit=ou, fmt=
"(T3,A)") &
1114 "XAS_TDP| Tamm-Dancoff Approximation (TDA): Off"
1118 IF (xas_tdp_control%dipole_form ==
xas_dip_vel)
THEN
1119 WRITE (unit=ou, fmt=
"(T3,A)") &
1120 "XAS_TDP| Transition Dipole Representation: VELOCITY"
1122 WRITE (unit=ou, fmt=
"(T3,A)") &
1123 "XAS_TDP| Transition Dipole Representation: LENGTH"
1127 IF (xas_tdp_control%do_quad)
THEN
1128 WRITE (unit=ou, fmt=
"(T3,A)") &
1129 "XAS_TDP| Transition Quadrupole: On"
1133 IF (xas_tdp_control%eps_pgf > 0.0_dp)
THEN
1134 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1135 "XAS_TDP| EPS_PGF_XAS: ", xas_tdp_control%eps_pgf
1137 WRITE (unit=ou, fmt=
"(T3,A,ES7.1,A)") &
1138 "XAS_TDP| EPS_PGF_XAS: ", dft_control%qs_control%eps_pgf_orb,
" (= EPS_PGF_ORB)"
1142 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1143 "XAS_TDP| EPS_FILTER: ", xas_tdp_control%eps_filter
1146 IF (xas_tdp_control%do_xc)
THEN
1147 WRITE (unit=ou, fmt=
"(T3,A)") &
1148 "XAS_TDP| Radial Grid(s) Info: Kind, na, nr"
1149 DO i = 1,
SIZE(xas_tdp_control%grid_info, 1)
1150 WRITE (unit=ou, fmt=
"(T3,A,A6,A,A,A,A)") &
1151 " ", trim(xas_tdp_control%grid_info(i, 1)),
", ", &
1152 trim(xas_tdp_control%grid_info(i, 2)),
", ", trim(xas_tdp_control%grid_info(i, 3))
1157 IF (.NOT. xas_tdp_control%do_coulomb)
THEN
1158 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1159 "XAS_TDP| No kernel (standard DFT)"
1163 IF (xas_tdp_control%do_xc)
THEN
1165 WRITE (unit=ou, fmt=
"(/,T3,A,F5.2,A)") &
1166 "XAS_TDP| RI Region's Radius: ", xas_tdp_control%ri_radius*
angstrom,
" Ang"
1168 WRITE (unit=ou, fmt=
"(T3,A,/)") &
1169 "XAS_TDP| XC Kernel Functional(s) used for the kernel:"
1171 IF (qs_env%do_rixs)
THEN
1176 CALL xc_write(ou, kernel_section, lsd=.true.)
1180 IF (xas_tdp_control%do_hfx)
THEN
1181 WRITE (unit=ou, fmt=
"(/,T3,A,/,/,T3,A,F5.3)") &
1182 "XAS_TDP| Exact Exchange Kernel: Yes ", &
1183 "EXACT_EXCHANGE| Scale: ", xas_tdp_control%sx
1185 WRITE (unit=ou, fmt=
"(T3,A)") &
1186 "EXACT_EXCHANGE| Potential : Coulomb"
1188 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,A)") &
1189 "EXACT_EXCHANGE| Potential: Truncated Coulomb", &
1190 "EXACT_EXCHANGE| Range: ", xas_tdp_control%x_potential%cutoff_radius*
angstrom,
", (Ang)", &
1191 "EXACT_EXCHANGE| T_C_G_DATA: ", trim(xas_tdp_control%x_potential%filename)
1193 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,F5.2,A,/,T3,A,ES7.1)") &
1194 "EXACT_EXCHANGE| Potential: Short Range", &
1195 "EXACT_EXCHANGE| Omega: ", xas_tdp_control%x_potential%omega,
", (1/a0)", &
1196 "EXACT_EXCHANGE| Effective Range: ", xas_tdp_control%x_potential%cutoff_radius*
angstrom,
", (Ang)", &
1197 "EXACT_EXCHANGE| EPS_RANGE: ", xas_tdp_control%eps_range
1199 IF (xas_tdp_control%eps_screen > 1.0e-16)
THEN
1200 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1201 "EXACT_EXCHANGE| EPS_SCREENING: ", xas_tdp_control%eps_screen
1205 IF (xas_tdp_control%do_ri_metric)
THEN
1207 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1208 "EXACT_EXCHANGE| Using a RI metric"
1209 IF (xas_tdp_control%ri_m_potential%potential_type ==
do_potential_id)
THEN
1210 WRITE (unit=ou, fmt=
"(T3,A)") &
1211 "EXACT_EXCHANGE RI_METRIC| Potential : Overlap"
1213 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,A)") &
1214 "EXACT_EXCHANGE RI_METRIC| Potential: Truncated Coulomb", &
1215 "EXACT_EXCHANGE RI_METRIC| Range: ", xas_tdp_control%ri_m_potential%cutoff_radius &
1217 "EXACT_EXCHANGE RI_METRIC| T_C_G_DATA: ", trim(xas_tdp_control%ri_m_potential%filename)
1219 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,F5.2,A,/,T3,A,ES7.1)") &
1220 "EXACT_EXCHANGE RI_METRIC| Potential: Short Range", &
1221 "EXACT_EXCHANGE RI_METRIC| Omega: ", xas_tdp_control%ri_m_potential%omega,
", (1/a0)", &
1222 "EXACT_EXCHANGE RI_METRIC| Effective Range: ", &
1223 xas_tdp_control%ri_m_potential%cutoff_radius*
angstrom,
", (Ang)", &
1224 "EXACT_EXCHANGE RI_METRIC| EPS_RANGE: ", xas_tdp_control%eps_range
1228 WRITE (unit=ou, fmt=
"(/,T3,A,/)") &
1229 "XAS_TDP| Exact Exchange Kernel: No "
1233 WRITE (unit=ou, fmt=
"(/,T3,A,F5.2)") &
1234 "XAS_TDP| Overlap matrix occupation: ", occ
1237 IF (xas_tdp_control%do_gw2x)
THEN
1238 WRITE (unit=ou, fmt=
"(T3,A,/)") &
1239 "XAS_TDP| GW2X correction enabled"
1241 IF (xas_tdp_control%xps_only)
THEN
1242 WRITE (unit=ou, fmt=
"(T3,A)") &
1243 "GW2X| Only computing ionizations potentials for XPS"
1246 IF (xas_tdp_control%pseudo_canonical)
THEN
1247 WRITE (unit=ou, fmt=
"(T3,A)") &
1248 "GW2X| Using the pseudo-canonical scheme"
1250 WRITE (unit=ou, fmt=
"(T3,A)") &
1251 "GW2X| Using the GW2X* scheme"
1254 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1255 "GW2X| EPS_GW2X: ", xas_tdp_control%gw2x_eps
1257 WRITE (unit=ou, fmt=
"(T3,A,I5)") &
1258 "GW2X| contraction batch size: ", xas_tdp_control%batch_size
1260 IF ((int(xas_tdp_control%c_os) /= 1) .OR. (int(xas_tdp_control%c_ss) /= 1))
THEN
1261 WRITE (unit=ou, fmt=
"(T3,A,F7.4,/,T3,A,F7.4)") &
1262 "GW2X| Same-spin scaling factor: ", xas_tdp_control%c_ss, &
1263 "GW2X| Opposite-spin scaling factor: ", xas_tdp_control%c_os
1268 END SUBROUTINE print_info
1283 SUBROUTINE assign_mos_to_ex_atoms(xas_tdp_env, xas_tdp_control, qs_env)
1289 INTEGER :: at_index, iat, iat_memo, imo, ispin, &
1290 n_atoms, n_search, nex_atoms, nspins
1291 INTEGER,
DIMENSION(3) :: perd_init
1292 INTEGER,
DIMENSION(:, :, :),
POINTER :: mos_of_ex_atoms
1293 REAL(
dp) :: dist, dist_min
1294 REAL(
dp),
DIMENSION(3) :: at_pos, r_ac, wfn_center
1299 NULLIFY (localized_wfn_control, mos_of_ex_atoms, cell, particle_set)
1302 mos_of_ex_atoms => xas_tdp_env%mos_of_ex_atoms
1303 mos_of_ex_atoms(:, :, :) = -1
1304 n_search = xas_tdp_control%n_search
1305 nex_atoms = xas_tdp_env%nex_atoms
1306 localized_wfn_control => xas_tdp_env%qs_loc_env%localized_wfn_control
1307 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, cell=cell)
1308 n_atoms =
SIZE(particle_set)
1309 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1312 perd_init = cell%perd
1316 DO ispin = 1, nspins
1317 DO imo = 1, n_search
1319 wfn_center(1:3) = localized_wfn_control%centers_set(ispin)%array(1:3, imo)
1323 dist_min = 10000.0_dp
1325 at_pos = particle_set(iat)%r
1326 r_ac =
pbc(at_pos, wfn_center, cell)
1330 IF (dist < dist_min)
THEN
1337 IF (any(xas_tdp_env%ex_atom_indices == iat_memo))
THEN
1338 at_index =
locate(xas_tdp_env%ex_atom_indices, iat_memo)
1339 mos_of_ex_atoms(imo, at_index, ispin) = 1
1345 cell%perd = perd_init
1347 END SUBROUTINE assign_mos_to_ex_atoms
1359 SUBROUTINE reinit_qs_loc_env(qs_loc_env, n_loc_states, do_uks, qs_env)
1362 INTEGER,
INTENT(IN) :: n_loc_states
1363 LOGICAL,
INTENT(IN) :: do_uks
1366 INTEGER :: i, nspins
1375 loc_wfn_control => qs_loc_env%localized_wfn_control
1380 loc_wfn_control%nloc_states(:) = n_loc_states
1381 loc_wfn_control%eps_occ = 0.0_dp
1382 loc_wfn_control%lu_bound_states(1, :) = 1
1383 loc_wfn_control%lu_bound_states(2, :) = n_loc_states
1385 loc_wfn_control%do_homo = .true.
1386 ALLOCATE (loc_wfn_control%loc_states(n_loc_states, 2))
1387 DO i = 1, n_loc_states
1388 loc_wfn_control%loc_states(i, :) = i
1391 nspins = 1;
IF (do_uks) nspins = 2
1392 CALL set_loc_centers(loc_wfn_control, loc_wfn_control%nloc_states, nspins=nspins)
1395 CALL qs_loc_env_init(qs_loc_env, loc_wfn_control, qs_env, do_localize=.true.)
1397 CALL qs_loc_env_init(qs_loc_env, loc_wfn_control, qs_env, myspin=1, do_localize=.true.)
1400 END SUBROUTINE reinit_qs_loc_env
1410 SUBROUTINE diagonalize_assigned_mo_subset(xas_tdp_env, xas_tdp_control, qs_env)
1416 INTEGER :: i, iat, ilmo, ispin, nao, nlmo, nspins
1417 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: evals
1420 TYPE(
cp_fm_type) :: evecs, ks_fm, lmo_fm, work
1426 NULLIFY (mos, mo_coeff, matrix_ks, para_env, blacs_env, lmo_struct, ks_struct)
1429 CALL get_qs_env(qs_env, mos=mos, matrix_ks=matrix_ks, para_env=para_env, blacs_env=blacs_env)
1431 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1434 DO ispin = 1, nspins
1435 DO iat = 1, xas_tdp_env%nex_atoms
1438 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, nao=nao)
1441 nlmo = count(xas_tdp_env%mos_of_ex_atoms(:, iat, ispin) == 1)
1443 para_env=para_env, context=blacs_env)
1448 para_env=para_env, context=blacs_env)
1454 DO ilmo = 1, xas_tdp_control%n_search
1455 IF (xas_tdp_env%mos_of_ex_atoms(ilmo, iat, ispin) == -1) cycle
1460 s_firstcol=ilmo, t_firstrow=1, t_firstcol=i)
1466 CALL parallel_gemm(
'T',
'N', nlmo, nlmo, nao, 1.0_dp, lmo_fm, work, 0.0_dp, ks_fm)
1469 ALLOCATE (evals(nlmo))
1474 CALL parallel_gemm(
'N',
'N', nao, nlmo, nlmo, 1.0_dp, lmo_fm, evecs, 0.0_dp, work)
1478 DO ilmo = 1, xas_tdp_control%n_search
1479 IF (xas_tdp_env%mos_of_ex_atoms(ilmo, iat, ispin) == -1) cycle
1483 s_firstcol=i, t_firstrow=1, t_firstcol=ilmo)
1497 END SUBROUTINE diagonalize_assigned_mo_subset
1508 SUBROUTINE assign_mos_to_donor_state(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
1515 INTEGER :: at_index, i, iat, imo, ispin, l, my_mo, &
1516 n_search, n_states, nao, ndo_so, nj, &
1517 nsgf_kind, nsgf_sto, nspins, &
1519 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: my_mos
1520 INTEGER,
DIMENSION(2) :: next_best_overlap_ind
1521 INTEGER,
DIMENSION(4, 7) :: ne
1522 INTEGER,
DIMENSION(:),
POINTER :: first_sgf, lq, nq
1523 INTEGER,
DIMENSION(:, :, :),
POINTER :: mos_of_ex_atoms
1526 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) ::
diag, overlap, sto_overlap
1527 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: max_overlap
1528 REAL(
dp),
DIMENSION(2) :: next_best_overlap
1529 REAL(
dp),
DIMENSION(:),
POINTER :: mo_evals, zeta
1530 REAL(
dp),
DIMENSION(:, :),
POINTER :: overlap_matrix, tmp_coeff
1534 TYPE(
cp_fm_type),
POINTER :: gs_coeffs, mo_coeff
1540 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
1543 NULLIFY (sto_basis_set, sto_to_gto_basis_set, qs_kind_set, kind_basis_set, lq, nq, zeta)
1544 NULLIFY (overlap_matrix, mos, mo_coeff, mos_of_ex_atoms, tmp_coeff, first_sgf, particle_set)
1545 NULLIFY (mo_evals, matrix_ks, para_env, blacs_env)
1546 NULLIFY (eval_mat_struct, gs_struct, gs_coeffs)
1550 CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set, mos=mos, particle_set=particle_set, &
1551 matrix_ks=matrix_ks, para_env=para_env, blacs_env=blacs_env)
1553 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1564 ELSE IF (donor_state%state_type ==
xas_2s_type)
THEN
1568 ELSE IF (donor_state%state_type ==
xas_2p_type)
THEN
1573 cpabort(
"Procedure for required type not implemented")
1575 ALLOCATE (my_mos(n_states, nspins))
1576 ALLOCATE (max_overlap(n_states, nspins))
1579 CALL get_qs_kind(qs_kind_set(donor_state%kind_index), zeff=zeff)
1587 ne(l, i) =
ptable(zval)%e_conv(l - 1) - 2*nj*(i - l)
1588 ne(l, i) = max(ne(l, i), 0)
1589 ne(l, i) = min(ne(l, i), 2*nj)
1594 zeta(1) =
srules(zval, ne, nq(1), lq(1))
1601 DEALLOCATE (nq, lq, zeta)
1605 gto_basis_set=sto_to_gto_basis_set, &
1607 sto_to_gto_basis_set%norm_type = 2
1611 CALL get_qs_kind(qs_kind_set(donor_state%kind_index), basis_set=kind_basis_set)
1616 ALLOCATE (overlap_matrix(nsgf_sto, nsgf_kind))
1626 mos_of_ex_atoms => xas_tdp_env%mos_of_ex_atoms
1627 n_search = xas_tdp_control%n_search
1628 at_index = donor_state%at_index
1629 iat =
locate(xas_tdp_env%ex_atom_indices, at_index)
1630 ALLOCATE (first_sgf(
SIZE(particle_set)))
1631 CALL get_particle_set(particle_set=particle_set, qs_kind_set=qs_kind_set, first_sgf=first_sgf)
1632 ALLOCATE (tmp_coeff(nsgf_kind, 1))
1633 ALLOCATE (sto_overlap(nsgf_kind))
1634 ALLOCATE (overlap(n_search))
1636 next_best_overlap = 0.0_dp
1637 max_overlap = 0.0_dp
1639 DO ispin = 1, nspins
1641 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, nao=nao)
1645 DO imo = 1, n_search
1646 IF (mos_of_ex_atoms(imo, iat, ispin) > 0)
THEN
1648 sto_overlap = 0.0_dp
1652 CALL cp_fm_get_submatrix(fm=mo_coeff, target_m=tmp_coeff, start_row=first_sgf(at_index), &
1653 start_col=imo, n_rows=nsgf_kind, n_cols=1, transpose=.false.)
1656 CALL dgemm(
'N',
'N', nsgf_sto, 1, nsgf_kind, 1.0_dp, overlap_matrix, nsgf_sto, &
1657 tmp_coeff, nsgf_kind, 0.0_dp, sto_overlap, nsgf_sto)
1662 overlap(imo) = sum(abs(sto_overlap))
1669 my_mo = maxloc(overlap, 1)
1670 my_mos(i, ispin) = my_mo
1671 max_overlap(i, ispin) = maxval(overlap, 1)
1672 overlap(my_mo) = 0.0_dp
1675 next_best_overlap(ispin) = maxval(overlap, 1)
1676 next_best_overlap_ind(ispin) = maxloc(overlap, 1)
1684 DEALLOCATE (overlap_matrix, tmp_coeff)
1687 IF (all(my_mos > 0) .AND. all(my_mos <= n_search))
THEN
1689 ALLOCATE (donor_state%mo_indices(n_states, nspins))
1690 donor_state%mo_indices = my_mos
1691 donor_state%ndo_mo = n_states
1695 para_env=para_env, context=blacs_env)
1696 ALLOCATE (donor_state%gs_coeffs)
1699 IF (.NOT.
ASSOCIATED(xas_tdp_env%mo_coeff))
THEN
1700 ALLOCATE (xas_tdp_env%mo_coeff(nspins))
1703 DO ispin = 1, nspins
1704 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff)
1706 IF (.NOT.
ASSOCIATED(xas_tdp_env%mo_coeff(ispin)%local_data))
THEN
1709 matrix_struct=matrix_struct)
1710 CALL cp_fm_create(xas_tdp_env%mo_coeff(ispin), matrix_struct)
1711 CALL cp_fm_to_fm(mo_coeff, xas_tdp_env%mo_coeff(ispin))
1716 ncol=1, s_firstrow=1, s_firstcol=my_mos(i, ispin), &
1717 t_firstrow=1, t_firstcol=(ispin - 1)*n_states + i)
1720 gs_coeffs => donor_state%gs_coeffs
1723 ALLOCATE (donor_state%contract_coeffs(nsgf_kind, n_states*nspins))
1724 CALL cp_fm_get_submatrix(gs_coeffs, donor_state%contract_coeffs, start_row=first_sgf(at_index), &
1725 start_col=1, n_rows=nsgf_kind, n_cols=n_states*nspins)
1730 IF (.NOT. xas_tdp_control%do_loc .AND. .NOT. xas_tdp_control%do_roks)
THEN
1731 IF (output_unit > 0)
THEN
1732 WRITE (unit=output_unit, fmt=
"(T5,A,/,T5,A,/,T5,A)") &
1733 "The following canonical MO(s) have been associated with the donor state(s)", &
1734 "based on the overlap with the components of a minimal STO basis: ", &
1735 " Spin MO index overlap(sum)"
1738 ALLOCATE (donor_state%energy_evals(n_states, nspins))
1739 donor_state%energy_evals = 0.0_dp
1742 DO ispin = 1, nspins
1743 CALL get_mo_set(mos(ispin), eigenvalues=mo_evals)
1745 donor_state%energy_evals(i, ispin) = mo_evals(my_mos(i, ispin))
1747 IF (output_unit > 0)
THEN
1748 WRITE (unit=output_unit, fmt=
"(T46,I4,I11,F17.5)") &
1749 ispin, my_mos(i, ispin), max_overlap(i, ispin)
1757 IF (output_unit > 0)
THEN
1758 WRITE (unit=output_unit, fmt=
"(T5,A,/,T5,A,/,T5,A)") &
1759 "The following localized MO(s) have been associated with the donor state(s)", &
1760 "based on the overlap with the components of a minimal STO basis: ", &
1761 " Spin MO index overlap(sum)"
1765 DO ispin = 1, nspins
1769 IF (output_unit > 0)
THEN
1770 WRITE (unit=output_unit, fmt=
"(T46,I4,I11,F17.5)") &
1771 ispin, my_mos(i, ispin), max_overlap(i, ispin)
1779 ndo_so = nspins*n_states
1782 para_env=para_env, context=blacs_env)
1784 ALLOCATE (
diag(ndo_so))
1786 IF (.NOT. xas_tdp_control%do_roks)
THEN
1788 ALLOCATE (donor_state%energy_evals(n_states, nspins))
1789 donor_state%energy_evals = 0.0_dp
1792 DO ispin = 1, nspins
1794 CALL parallel_gemm(
'T',
'N', ndo_so, ndo_so, nao, 1.0_dp, gs_coeffs, work_mat, 0.0_dp, eval_mat)
1798 donor_state%energy_evals(:, ispin) =
diag((ispin - 1)*n_states + 1:ispin*n_states)
1804 ALLOCATE (donor_state%energy_evals(n_states, 2))
1805 donor_state%energy_evals = 0.0_dp
1810 CALL parallel_gemm(
'T',
'N', ndo_so, ndo_so, nao, 1.0_dp, gs_coeffs, work_mat, 0.0_dp, eval_mat)
1813 donor_state%energy_evals(:, ispin) =
diag(:)
1828 ALLOCATE (donor_state%gw2x_evals(
SIZE(donor_state%energy_evals, 1),
SIZE(donor_state%energy_evals, 2)))
1829 donor_state%gw2x_evals(:, :) = donor_state%energy_evals(:, :)
1833 DEALLOCATE (first_sgf)
1835 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T5,A)")
" "
1837 DO ispin = 1, nspins
1838 IF (output_unit > 0)
THEN
1839 WRITE (unit=output_unit, fmt=
"(T5,A,I1,A,F7.5,A,I4)") &
1840 "The next best overlap for spin ", ispin,
" is ", next_best_overlap(ispin), &
1841 " for MO with index ", next_best_overlap_ind(ispin)
1844 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T5,A)")
" "
1847 cpabort(
"A core donor state could not be assigned MO(s). Increasing NSEARCH might help.")
1850 END SUBROUTINE assign_mos_to_donor_state
1860 SUBROUTINE find_mo_centers(xas_tdp_env, xas_tdp_control, qs_env)
1866 INTEGER :: dim_op, i, ispin, j, n_centers, nao, &
1868 REAL(
dp),
DIMENSION(6) :: weights
1873 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:, :) :: zij_fm_set
1874 TYPE(
cp_fm_type),
DIMENSION(:),
POINTER :: moloc_coeff
1876 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: op_sm_set
1881 NULLIFY (qs_loc_env, cell, print_loc_section, op_sm_set, moloc_coeff, vectors)
1882 NULLIFY (tmp_fm_struct, para_env, blacs_env, prog_run_info)
1885 print_loc_section => xas_tdp_control%print_loc_subsection
1886 n_centers = xas_tdp_control%n_search
1887 CALL get_qs_env(qs_env=qs_env, para_env=para_env, blacs_env=blacs_env, cell=cell)
1895 CALL reinit_qs_loc_env(xas_tdp_env%qs_loc_env, n_centers, xas_tdp_control%do_uks, qs_env)
1896 qs_loc_env => xas_tdp_env%qs_loc_env
1899 CALL get_qs_loc_env(qs_loc_env=qs_loc_env, weights=weights, op_sm_set=op_sm_set, &
1900 moloc_coeff=moloc_coeff)
1903 vectors => moloc_coeff(1)
1908 ncol_global=n_centers, nrow_global=n_centers)
1910 IF (cell%orthorhombic)
THEN
1915 ALLOCATE (zij_fm_set(2, dim_op))
1923 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1925 DO ispin = 1, nspins
1927 vectors => moloc_coeff(ispin)
1932 CALL parallel_gemm(
"T",
"N", n_centers, n_centers, nao, 1.0_dp, vectors, opvec, 0.0_dp, &
1939 cell=cell, weights=weights, ispin=ispin, &
1940 print_loc_section=print_loc_section, only_initial_out=.true.)
1949 qs_loc_env%do_localize = xas_tdp_control%do_loc
1951 END SUBROUTINE find_mo_centers
1960 SUBROUTINE print_checks(xas_tdp_env, xas_tdp_control, qs_env)
1966 CHARACTER(LEN=default_string_length) :: kind_name
1967 INTEGER :: current_state_index, iat, iatom, ikind, &
1968 istate, output_unit, tmp_index
1969 INTEGER,
DIMENSION(:),
POINTER :: atoms_of_kind
1973 NULLIFY (atomic_kind_set, atoms_of_kind, current_state)
1977 IF (output_unit > 0)
THEN
1978 WRITE (output_unit,
"(/,T3,A,/,T3,A,/,T3,A)") &
1979 "# Check the donor states for their quality. They need to have a well defined type ", &
1980 " (1s, 2s, etc) which is indicated by the overlap. They also need to be localized, ", &
1981 " for which the Mulliken population analysis is one indicator (must be close to 1.0)"
1985 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
1986 current_state_index = 1
1989 DO ikind = 1,
SIZE(atomic_kind_set)
1991 CALL get_atomic_kind(atomic_kind=atomic_kind_set(ikind), name=kind_name, &
1992 atom_list=atoms_of_kind)
1994 IF (.NOT. any(xas_tdp_env%ex_kind_indices == ikind)) cycle
1997 DO iat = 1,
SIZE(atoms_of_kind)
1998 iatom = atoms_of_kind(iat)
2000 IF (.NOT. any(xas_tdp_env%ex_atom_indices == iatom)) cycle
2001 tmp_index =
locate(xas_tdp_env%ex_atom_indices, iatom)
2004 DO istate = 1,
SIZE(xas_tdp_env%state_types, 1)
2006 IF (xas_tdp_env%state_types(istate, tmp_index) ==
xas_not_excited) cycle
2008 current_state => xas_tdp_env%donor_states(current_state_index)
2010 at_symbol=kind_name, kind_index=ikind, &
2011 state_type=xas_tdp_env%state_types(istate, tmp_index))
2013 IF (output_unit > 0)
THEN
2014 WRITE (output_unit,
"(/,T4,A,A2,A,I4,A,A,A)") &
2015 "-Donor state of type ", xas_tdp_env%state_type_char(current_state%state_type), &
2016 " for atom", current_state%at_index,
" of kind ", trim(current_state%at_symbol),
":"
2020 CALL assign_mos_to_donor_state(current_state, xas_tdp_env, xas_tdp_control, qs_env)
2021 CALL perform_mulliken_on_donor_state(current_state, qs_env)
2023 current_state_index = current_state_index + 1
2024 NULLIFY (current_state)
2030 IF (output_unit > 0)
THEN
2031 WRITE (output_unit,
"(/,T5,A)") &
2032 "Use LOCALIZE and/or increase N_SEARCH for better results, if so required."
2035 END SUBROUTINE print_checks
2045 SUBROUTINE compute_lenrep_multipole(iatom, xas_tdp_env, xas_tdp_control, qs_env)
2047 INTEGER,
INTENT(IN) :: iatom
2053 REAL(
dp),
DIMENSION(3) :: rc
2057 NULLIFY (work, particle_set)
2059 CALL get_qs_env(qs_env, particle_set=particle_set)
2060 rc = particle_set(iatom)%r
2063 IF (xas_tdp_control%dipole_form ==
xas_dip_len)
THEN
2065 CALL dbcsr_set(xas_tdp_env%dipmat(i)%matrix, 0.0_dp)
2066 work(i)%matrix => xas_tdp_env%dipmat(i)%matrix
2070 IF (xas_tdp_control%do_quad)
THEN
2072 CALL dbcsr_set(xas_tdp_env%quadmat(i)%matrix, 0.0_dp)
2073 work(3 + i)%matrix => xas_tdp_env%quadmat(i)%matrix
2076 IF (xas_tdp_control%dipole_form ==
xas_dip_vel) order = -2
2080 CALL rrc_xyz_ao(work, qs_env, rc, order=order, minimum_image=.true.)
2083 END SUBROUTINE compute_lenrep_multipole
2097 SUBROUTINE compute_dipole_fosc(donor_state, xas_tdp_control, xas_tdp_env)
2103 CHARACTER(len=*),
PARAMETER :: routinen =
'compute_dipole_fosc'
2105 INTEGER :: handle, iosc, j, nao, ndo_mo, ndo_so, &
2107 LOGICAL :: do_sc, do_sg
2108 REAL(
dp) :: alpha_xyz, beta_xyz, osc_xyz, pref
2109 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: alpha_contr, beta_contr, tot_contr
2110 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: dip_block
2111 REAL(
dp),
DIMENSION(:),
POINTER :: lr_evals
2112 REAL(
dp),
DIMENSION(:, :),
POINTER :: alpha_osc, beta_osc, osc_str
2120 NULLIFY (dipmat, col_struct, mat_struct, para_env, blacs_env, lr_coeffs)
2121 NULLIFY (lr_evals, osc_str, alpha_osc, beta_osc)
2123 CALL timeset(routinen, handle)
2126 do_sc = xas_tdp_control%do_spin_cons
2127 do_sg = xas_tdp_control%do_singlet
2130 lr_evals => donor_state%sc_evals
2131 lr_coeffs => donor_state%sc_coeffs
2132 ELSE IF (do_sg)
THEN
2134 lr_evals => donor_state%sg_evals
2135 lr_coeffs => donor_state%sg_coeffs
2137 cpabort(
"Dipole oscilaltor strength only for singlets and spin-conserving excitations.")
2139 ndo_mo = donor_state%ndo_mo
2140 ndo_so = ndo_mo*nspins
2141 ngs = ndo_so;
IF (xas_tdp_control%do_roks) ngs = ndo_mo
2142 nosc =
SIZE(lr_evals)
2143 ALLOCATE (donor_state%osc_str(nosc, 4), donor_state%alpha_osc(nosc, 4), donor_state%beta_osc(nosc, 4))
2144 osc_str => donor_state%osc_str
2145 alpha_osc => donor_state%alpha_osc
2146 beta_osc => donor_state%beta_osc
2150 dipmat => xas_tdp_env%dipmat
2153 CALL cp_fm_get_info(donor_state%gs_coeffs, matrix_struct=col_struct, para_env=para_env, &
2154 context=blacs_env, nrow_global=nao)
2156 nrow_global=ndo_so*nosc, ncol_global=ngs)
2160 ALLOCATE (tot_contr(ndo_mo), dip_block(ndo_so, ngs), alpha_contr(ndo_mo), beta_contr(ndo_mo))
2161 pref = 2.0_dp;
IF (do_sc) pref = 1.0_dp
2169 CALL parallel_gemm(
'T',
'N', ndo_so*nosc, ngs, nao, 1.0_dp, lr_coeffs, col_work, 0.0_dp, mat_work)
2175 CALL cp_fm_get_submatrix(fm=mat_work, target_m=dip_block, start_row=(iosc - 1)*ndo_so + 1, &
2176 start_col=1, n_rows=ndo_so, n_cols=ngs)
2179 ELSE IF (do_sc .AND. xas_tdp_control%do_uks)
THEN
2180 alpha_contr(:) =
get_diag(dip_block(1:ndo_mo, 1:ndo_mo))
2181 beta_contr(:) =
get_diag(dip_block(ndo_mo + 1:ndo_so, ndo_mo + 1:ndo_so))
2182 tot_contr(:) = alpha_contr(:) + beta_contr(:)
2185 alpha_contr(:) =
get_diag(dip_block(1:ndo_mo, :))
2186 beta_contr(:) =
get_diag(dip_block(ndo_mo + 1:ndo_so, :))
2187 tot_contr(:) = alpha_contr(:) + beta_contr(:)
2190 osc_xyz = sum(tot_contr)**2
2191 alpha_xyz = sum(alpha_contr)**2
2192 beta_xyz = sum(beta_contr)**2
2194 alpha_osc(iosc, 4) = alpha_osc(iosc, 4) + alpha_xyz
2195 alpha_osc(iosc, j) = alpha_xyz
2197 beta_osc(iosc, 4) = beta_osc(iosc, 4) + beta_xyz
2198 beta_osc(iosc, j) = beta_xyz
2200 osc_str(iosc, 4) = osc_str(iosc, 4) + osc_xyz
2201 osc_str(iosc, j) = osc_xyz
2208 IF (xas_tdp_control%dipole_form ==
xas_dip_len)
THEN
2209 osc_str(:, j) = pref*2.0_dp/3.0_dp*lr_evals(:)*osc_str(:, j)
2210 alpha_osc(:, j) = pref*2.0_dp/3.0_dp*lr_evals(:)*alpha_osc(:, j)
2211 beta_osc(:, j) = pref*2.0_dp/3.0_dp*lr_evals(:)*beta_osc(:, j)
2213 osc_str(:, j) = pref*2.0_dp/3.0_dp/lr_evals(:)*osc_str(:, j)
2214 alpha_osc(:, j) = pref*2.0_dp/3.0_dp/lr_evals(:)*alpha_osc(:, j)
2215 beta_osc(:, j) = pref*2.0_dp/3.0_dp/lr_evals(:)*beta_osc(:, j)
2224 CALL timestop(handle)
2226 END SUBROUTINE compute_dipole_fosc
2236 SUBROUTINE compute_quadrupole_fosc(donor_state, xas_tdp_control, xas_tdp_env)
2242 CHARACTER(len=*),
PARAMETER :: routinen =
'compute_quadrupole_fosc'
2244 INTEGER :: handle, iosc, j, nao, ndo_mo, ndo_so, &
2246 LOGICAL :: do_sc, do_sg
2248 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: tot_contr, trace
2249 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: quad_block
2250 REAL(
dp),
DIMENSION(:),
POINTER :: lr_evals, osc_str
2258 NULLIFY (lr_evals, osc_str, lr_coeffs, col_struct, mat_struct, para_env)
2261 CALL timeset(routinen, handle)
2264 do_sc = xas_tdp_control%do_spin_cons
2265 do_sg = xas_tdp_control%do_singlet
2268 lr_evals => donor_state%sc_evals
2269 lr_coeffs => donor_state%sc_coeffs
2270 ELSE IF (do_sg)
THEN
2272 lr_evals => donor_state%sg_evals
2273 lr_coeffs => donor_state%sg_coeffs
2275 cpabort(
"Quadrupole oscillator strengths only for singlet and spin-conserving excitations")
2277 ndo_mo = donor_state%ndo_mo
2278 ndo_so = ndo_mo*nspins
2279 ngs = ndo_so;
IF (xas_tdp_control%do_roks) ngs = ndo_mo
2280 nosc =
SIZE(lr_evals)
2281 ALLOCATE (donor_state%quad_osc_str(nosc))
2282 osc_str => donor_state%quad_osc_str
2284 quadmat => xas_tdp_env%quadmat
2287 CALL cp_fm_get_info(donor_state%gs_coeffs, matrix_struct=col_struct, para_env=para_env, &
2288 context=blacs_env, nrow_global=nao)
2290 nrow_global=ndo_so*nosc, ncol_global=ngs)
2294 ALLOCATE (quad_block(ndo_so, ngs), tot_contr(ndo_mo))
2295 pref = 2.0_dp;
IF (do_sc) pref = 1.0_dp
2296 ALLOCATE (trace(nosc))
2305 CALL parallel_gemm(
'T',
'N', ndo_so*nosc, ngs, nao, 1.0_dp, lr_coeffs, col_work, 0.0_dp, mat_work)
2311 CALL cp_fm_get_submatrix(fm=mat_work, target_m=quad_block, start_row=(iosc - 1)*ndo_so + 1, &
2312 start_col=1, n_rows=ndo_so, n_cols=ngs)
2315 tot_contr(:) =
get_diag(quad_block)
2316 ELSE IF (do_sc .AND. xas_tdp_control%do_uks)
THEN
2317 tot_contr(:) =
get_diag(quad_block(1:ndo_mo, 1:ndo_mo))
2318 tot_contr(:) = tot_contr(:) +
get_diag(quad_block(ndo_mo + 1:ndo_so, ndo_mo + 1:ndo_so))
2321 tot_contr(:) =
get_diag(quad_block(1:ndo_mo, :))
2322 tot_contr(:) = tot_contr(:) +
get_diag(quad_block(ndo_mo + 1:ndo_so, :))
2326 IF (j == 1 .OR. j == 4 .OR. j == 6)
THEN
2327 osc_str(iosc) = osc_str(iosc) + sum(tot_contr)**2
2328 trace(iosc) = trace(iosc) + sum(tot_contr)
2332 osc_str(iosc) = osc_str(iosc) + 2.0_dp*sum(tot_contr)**2
2339 osc_str(:) = pref*1._dp/20._dp*
a_fine**2*lr_evals(:)**3*(osc_str(:) - 1._dp/3._dp*trace(:)**2)
2346 CALL timestop(handle)
2348 END SUBROUTINE compute_quadrupole_fosc
2357 SUBROUTINE write_mos_to_ex_atoms_association(xas_tdp_env, xas_tdp_control, qs_env)
2363 CHARACTER(LEN=default_string_length) :: kind_name
2364 INTEGER :: at_index, imo, ispin, nmo, nspins, &
2365 output_unit, tmp_index
2366 INTEGER,
DIMENSION(3) :: perd_init
2367 INTEGER,
DIMENSION(:),
POINTER :: ex_atom_indices
2368 INTEGER,
DIMENSION(:, :, :),
POINTER :: mos_of_ex_atoms
2369 REAL(
dp) :: dist, mo_spread
2370 REAL(
dp),
DIMENSION(3) :: at_pos, r_ac, wfn_center
2374 NULLIFY (cell, particle_set, mos_of_ex_atoms, ex_atom_indices)
2378 IF (output_unit > 0)
THEN
2379 WRITE (unit=output_unit, fmt=
"(/,T3,A,/,T3,A,/,T3,A)") &
2380 " Associated Associated Distance to MO spread (Ang^2)", &
2381 "Spin MO index atom index atom kind MO center (Ang) -w_i ln(|z_ij|^2)", &
2382 "---------------------------------------------------------------------------------"
2386 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
2387 mos_of_ex_atoms => xas_tdp_env%mos_of_ex_atoms
2388 ex_atom_indices => xas_tdp_env%ex_atom_indices
2389 nmo = xas_tdp_control%n_search
2390 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, cell=cell)
2393 perd_init = cell%perd
2398 DO ispin = 1, nspins
2401 IF (any(mos_of_ex_atoms(imo, :, ispin) == 1))
THEN
2402 tmp_index = maxloc(mos_of_ex_atoms(imo, :, ispin), 1)
2403 at_index = ex_atom_indices(tmp_index)
2404 kind_name = particle_set(at_index)%atomic_kind%name
2406 at_pos = particle_set(at_index)%r
2407 wfn_center = xas_tdp_env%qs_loc_env%localized_wfn_control%centers_set(ispin)%array(1:3, imo)
2408 r_ac =
pbc(at_pos, wfn_center, cell)
2413 mo_spread = xas_tdp_env%qs_loc_env%localized_wfn_control%centers_set(ispin)%array(4, imo)
2416 IF (output_unit > 0)
THEN
2417 WRITE (unit=output_unit, fmt=
"(T3,I4,I10,I14,A14,ES19.3,ES20.3)") &
2418 ispin, imo, at_index, trim(kind_name), dist, mo_spread
2425 IF (output_unit > 0)
THEN
2426 WRITE (unit=output_unit, fmt=
"(T3,A,/)") &
2427 "---------------------------------------------------------------------------------"
2431 cell%perd = perd_init
2433 END SUBROUTINE write_mos_to_ex_atoms_association
2444 SUBROUTINE perform_mulliken_on_donor_state(donor_state, qs_env)
2448 INTEGER :: at_index, i, ispin, nao, natom, ndo_mo, &
2449 ndo_so, nsgf, nspins, output_unit
2450 INTEGER,
DIMENSION(:),
POINTER :: first_sgf, last_sgf
2451 INTEGER,
DIMENSION(:, :),
POINTER :: mo_indices
2452 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: mul_pop, pop_mat
2453 REAL(
dp),
DIMENSION(:, :),
POINTER :: work_array
2461 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2463 NULLIFY (mo_indices, qs_kind_set, particle_set, first_sgf, work_array)
2464 NULLIFY (matrix_s, para_env, blacs_env, col_vect_struct, last_sgf)
2467 at_index = donor_state%at_index
2468 mo_indices => donor_state%mo_indices
2469 ndo_mo = donor_state%ndo_mo
2470 gs_coeffs => donor_state%gs_coeffs
2472 nspins = 1;
IF (
SIZE(mo_indices, 2) == 2) nspins = 2
2473 ndo_so = ndo_mo*nspins
2474 ALLOCATE (mul_pop(ndo_mo, nspins))
2477 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, qs_kind_set=qs_kind_set, &
2478 para_env=para_env, blacs_env=blacs_env, matrix_s=matrix_s)
2479 CALL cp_fm_get_info(gs_coeffs, nrow_global=nao, matrix_struct=col_vect_struct)
2481 natom =
SIZE(particle_set, 1)
2482 ALLOCATE (first_sgf(natom))
2483 ALLOCATE (last_sgf(natom))
2485 CALL get_particle_set(particle_set, qs_kind_set, first_sgf=first_sgf, last_sgf=last_sgf)
2486 nsgf = last_sgf(at_index) - first_sgf(at_index) + 1
2494 ALLOCATE (work_array(nsgf, ndo_so))
2495 ALLOCATE (pop_mat(ndo_so, ndo_so))
2497 CALL cp_fm_get_submatrix(fm=work_vect, target_m=work_array, start_row=first_sgf(at_index), &
2498 start_col=1, n_rows=nsgf, n_cols=ndo_so, transpose=.false.)
2500 CALL dgemm(
'T',
'N', ndo_so, ndo_so, nsgf, 1.0_dp, donor_state%contract_coeffs, nsgf, &
2501 work_array, nsgf, 0.0_dp, pop_mat, ndo_so)
2504 DO ispin = 1, nspins
2506 mul_pop(i, ispin) = pop_mat((ispin - 1)*ndo_mo + i, (ispin - 1)*ndo_mo + i)
2511 IF (output_unit > 0)
THEN
2512 WRITE (unit=output_unit, fmt=
"(T5,A,/,T5,A)") &
2513 "Mulliken population analysis retricted to the associated MO(s) yields: ", &
2514 " Spin MO index charge"
2515 DO ispin = 1, nspins
2517 WRITE (unit=output_unit, fmt=
"(T51,I4,I10,F11.3)") &
2518 ispin, mo_indices(i, ispin), mul_pop(i, ispin)
2524 DEALLOCATE (first_sgf, last_sgf, work_array)
2527 END SUBROUTINE perform_mulliken_on_donor_state
2537 SUBROUTINE xas_tdp_post(ex_type, donor_state, xas_tdp_env, xas_tdp_section, qs_env)
2539 INTEGER,
INTENT(IN) :: ex_type
2545 CHARACTER(len=*),
PARAMETER :: routinen =
'xas_tdp_post'
2547 CHARACTER(len=default_string_length) :: domo, domon, excite, pos, xas_mittle
2548 INTEGER :: ex_state_idx, handle, ic, ido_mo, imo, irep, ispin, n_dependent, n_rep, nao, &
2549 ncubes, ndo_mo, ndo_so, nlumo, nmo, nspins, output_unit
2550 INTEGER,
DIMENSION(:),
POINTER :: bounds,
list, state_list
2551 LOGICAL :: append_cube, do_cubes, do_pdos, &
2553 REAL(
dp),
DIMENSION(:),
POINTER :: lr_evals
2554 REAL(
dp),
DIMENSION(:, :),
POINTER :: centers
2566 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2569 NULLIFY (atomic_kind_set, particle_set, qs_kind_set, mo_set, lr_evals, lr_coeffs)
2570 NULLIFY (mo_struct, para_env, blacs_env, fm_struct, matrix_s, print_key, logger)
2571 NULLIFY (bounds, state_list,
list, mos)
2575 do_pdos = .false.; do_cubes = .false.; do_wfn_restart = .false.
2578 "PRINT%PDOS"),
cp_p_file)) do_pdos = .true.
2581 "PRINT%CUBES"),
cp_p_file)) do_cubes = .true.
2584 "PRINT%RESTART_WFN"),
cp_p_file)) do_wfn_restart = .true.
2586 IF (.NOT. (do_pdos .OR. do_cubes .OR. do_wfn_restart))
RETURN
2588 CALL timeset(routinen, handle)
2591 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, particle_set=particle_set, &
2592 qs_kind_set=qs_kind_set, para_env=para_env, blacs_env=blacs_env, &
2593 matrix_s=matrix_s, mos=mos)
2595 SELECT CASE (ex_type)
2597 lr_evals => donor_state%sc_evals
2598 lr_coeffs => donor_state%sc_coeffs
2602 lr_evals => donor_state%sf_evals
2603 lr_coeffs => donor_state%sf_coeffs
2607 lr_evals => donor_state%sg_evals
2608 lr_coeffs => donor_state%sg_coeffs
2612 lr_evals => donor_state%tp_evals
2613 lr_coeffs => donor_state%tp_coeffs
2618 SELECT CASE (donor_state%state_type)
2627 ndo_mo = donor_state%ndo_mo
2628 ndo_so = ndo_mo*nspins
2629 nmo =
SIZE(lr_evals)
2633 nrow_global=nao, ncol_global=nmo)
2637 IF (do_wfn_restart)
THEN
2640 IF (.NOT. (nspins == 1 .AND. donor_state%state_type ==
xas_1s_type))
THEN
2641 cpabort(
"RESTART.wfn file only available for RKS K-edge XAS spectroscopy")
2644 CALL section_vals_val_get(xas_tdp_section,
"PRINT%RESTART_WFN%EXCITED_STATE_INDEX", n_rep_val=n_rep)
2648 i_rep_val=irep, i_val=ex_state_idx)
2649 cpassert(ex_state_idx <=
SIZE(lr_evals))
2655 IF (
SIZE(mos) == 1)
THEN
2656 restart_mos(ispin)%occupation_numbers = mos(1)%occupation_numbers/2
2660 CALL cp_fm_to_fm_submat(msource=lr_coeffs, mtarget=restart_mos(1)%mo_coeff, nrow=nao, &
2661 ncol=1, s_firstrow=1, s_firstcol=ex_state_idx, t_firstrow=1, &
2662 t_firstcol=donor_state%mo_indices(1, 1))
2664 xas_mittle =
'xasat'//trim(adjustl(
cp_to_string(donor_state%at_index)))//
'_'//trim(domo)// &
2665 '_'//trim(excite)//
'_idx'//trim(adjustl(
cp_to_string(ex_state_idx)))
2667 extension=
".wfn", file_status=
"REPLACE", &
2668 file_action=
"WRITE", file_form=
"UNFORMATTED", &
2669 middle_name=xas_mittle)
2672 qs_kind_set=qs_kind_set, ires=output_unit)
2687 IF (.NOT.
ASSOCIATED(xas_tdp_env%matrix_shalf) .AND. do_pdos)
THEN
2689 nrow_global=nao, ncol_global=nao)
2690 ALLOCATE (xas_tdp_env%matrix_shalf)
2695 CALL cp_fm_power(xas_tdp_env%matrix_shalf, work_fm, 0.5_dp, epsilon(0.0_dp), n_dependent)
2703 IF (output_unit > 0)
THEN
2704 WRITE (unit=output_unit, fmt=
"(/,T5,A,/,T5,A,/,T5,A)") &
2705 "Computing the PDOS of linear-response orbitals for spectral features analysis", &
2706 "Note: using standard PDOS routines => ignore mentions of KS states and MO ", &
2707 " occupation numbers. Eigenvalues in *.pdos files are excitations energies."
2712 IF (nlumo /= 0)
THEN
2713 cpwarn(
"NLUMO is irrelevant for XAS_TDP PDOS. It was overwritten to 0.")
2724 ncubes = bounds(2) - bounds(1) + 1
2725 IF (ncubes > 0)
THEN
2726 ALLOCATE (state_list(ncubes))
2728 state_list(ic) = bounds(1) + ic - 1
2732 IF (.NOT.
ASSOCIATED(state_list))
THEN
2739 IF (
ASSOCIATED(
list))
THEN
2741 DO ic = 1,
SIZE(
list)
2742 state_list(ncubes + ic) =
list(ic)
2744 ncubes = ncubes +
SIZE(
list)
2749 IF (.NOT.
ASSOCIATED(state_list))
THEN
2751 ALLOCATE (state_list(1))
2757 IF (append_cube) pos =
"APPEND"
2759 ALLOCATE (centers(6, ncubes))
2765 DO ido_mo = 1, ndo_mo
2766 DO ispin = 1, nspins
2770 CALL allocate_mo_set(mo_set, nao=nao, nmo=nmo, nelectron=nmo, n_el_f=real(nmo,
dp), &
2771 maxocc=1.0_dp, flexible_electron_count=0.0_dp)
2772 CALL init_mo_set(mo_set, fm_ref=mo_coeff, name=
"PDOS XAS_TDP MOs")
2773 mo_set%eigenvalues(:) = lr_evals(:)
2776 IF (nspins == 1 .AND. ndo_mo == 1)
THEN
2781 nrow=nao, ncol=1, s_firstrow=1, &
2782 s_firstcol=(imo - 1)*ndo_so + (ispin - 1)*ndo_mo + ido_mo, &
2783 t_firstrow=1, t_firstcol=imo)
2790 xas_mittle =
'xasat'//trim(adjustl(
cp_to_string(donor_state%at_index)))//
'_'// &
2791 trim(domon)//
'_'//trim(excite)
2795 qs_env, xas_tdp_section, ispin, xas_mittle, &
2796 external_matrix_shalf=xas_tdp_env%matrix_shalf)
2800 CALL qs_print_cubes(qs_env, mo_set%mo_coeff, ncubes, state_list, centers, &
2801 print_key=print_key, root=xas_mittle, ispin=ispin, &
2815 IF (do_cubes)
DEALLOCATE (centers, state_list)
2817 CALL timestop(handle)
2819 END SUBROUTINE xas_tdp_post
2829 SUBROUTINE make_lumo_guess(xas_tdp_env, xas_tdp_control, qs_env)
2831 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2832 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2833 TYPE(qs_environment_type),
POINTER :: qs_env
2835 CHARACTER(len=*),
PARAMETER :: routinen =
'make_lumo_guess'
2837 INTEGER :: handle, ispin, nao, nelec_spin(2), &
2838 nlumo(2), nocc(2), nspins
2840 REAL(dp),
ALLOCATABLE,
DIMENSION(:) :: evals
2841 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
2842 TYPE(cp_fm_struct_type),
POINTER :: fm_struct, lumo_struct
2843 TYPE(cp_fm_type) :: amatrix, bmatrix, evecs, work_fm
2844 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_ks, matrix_s
2845 TYPE(mp_para_env_type),
POINTER :: para_env
2847 NULLIFY (matrix_ks, matrix_s, para_env, blacs_env)
2848 NULLIFY (lumo_struct, fm_struct)
2850 CALL timeset(routinen, handle)
2852 do_os = xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks
2853 nspins = 1;
IF (do_os) nspins = 2
2854 ALLOCATE (xas_tdp_env%lumo_evecs(nspins))
2855 ALLOCATE (xas_tdp_env%lumo_evals(nspins))
2856 CALL get_qs_env(qs_env, matrix_ks=matrix_ks, matrix_s=matrix_s, nelectron_spin=nelec_spin, &
2857 para_env=para_env, blacs_env=blacs_env)
2858 CALL dbcsr_get_info(matrix_s(1)%matrix, nfullrows_total=nao)
2861 nlumo = nao - nelec_spin
2864 nlumo = nao - nelec_spin(1)/2
2865 nocc = nelec_spin(1)/2
2868 ALLOCATE (xas_tdp_env%ot_prec(nspins))
2870 DO ispin = 1, nspins
2873 CALL cp_fm_struct_create(fm_struct, para_env=para_env, context=blacs_env, &
2874 nrow_global=nao, ncol_global=nao)
2875 CALL cp_fm_create(amatrix, fm_struct)
2876 CALL cp_fm_create(bmatrix, fm_struct)
2877 CALL cp_fm_create(evecs, fm_struct)
2878 CALL cp_fm_create(work_fm, fm_struct)
2879 ALLOCATE (evals(nao))
2880 ALLOCATE (xas_tdp_env%lumo_evals(ispin)%array(nlumo(ispin)))
2882 CALL copy_dbcsr_to_fm(matrix_ks(ispin)%matrix, amatrix)
2883 CALL copy_dbcsr_to_fm(matrix_s(1)%matrix, bmatrix)
2886 CALL cp_fm_geeig(amatrix, bmatrix, evecs, evals, work_fm)
2889 CALL cp_fm_struct_create(lumo_struct, para_env=para_env, context=blacs_env, &
2890 nrow_global=nao, ncol_global=nlumo(ispin))
2891 CALL cp_fm_create(xas_tdp_env%lumo_evecs(ispin), lumo_struct)
2893 CALL cp_fm_to_fm_submat(evecs, xas_tdp_env%lumo_evecs(ispin), nrow=nao, &
2894 ncol=nlumo(ispin), s_firstrow=1, s_firstcol=nocc(ispin) + 1, &
2895 t_firstrow=1, t_firstcol=1)
2897 xas_tdp_env%lumo_evals(ispin)%array(1:nlumo(ispin)) = evals(nocc(ispin) + 1:nao)
2899 CALL build_ot_spin_prec(evecs, evals, ispin, xas_tdp_env, xas_tdp_control, qs_env)
2902 CALL cp_fm_release(amatrix)
2903 CALL cp_fm_release(bmatrix)
2904 CALL cp_fm_release(evecs)
2905 CALL cp_fm_release(work_fm)
2906 CALL cp_fm_struct_release(fm_struct)
2907 CALL cp_fm_struct_release(lumo_struct)
2911 CALL timestop(handle)
2913 END SUBROUTINE make_lumo_guess
2926 SUBROUTINE build_ot_spin_prec(evecs, evals, ispin, xas_tdp_env, xas_tdp_control, qs_env)
2928 TYPE(cp_fm_type),
INTENT(IN) :: evecs
2929 REAL(dp),
DIMENSION(:) :: evals
2931 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2932 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2933 TYPE(qs_environment_type),
POINTER :: qs_env
2935 CHARACTER(len=*),
PARAMETER :: routinen =
'build_ot_spin_prec'
2937 INTEGER :: handle, nao, nelec_spin(2), nguess, &
2941 REAL(dp),
ALLOCATABLE,
DIMENSION(:) :: scaling
2942 TYPE(cp_fm_struct_type),
POINTER :: fm_struct
2943 TYPE(cp_fm_type) :: fm_prec, work_fm
2944 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_s
2945 TYPE(mp_para_env_type),
POINTER :: para_env
2947 NULLIFY (fm_struct, para_env, matrix_s)
2949 CALL timeset(routinen, handle)
2951 do_os = xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks
2952 CALL get_qs_env(qs_env, para_env=para_env, nelectron_spin=nelec_spin, matrix_s=matrix_s)
2953 CALL cp_fm_get_info(evecs, nrow_global=nao, matrix_struct=fm_struct)
2954 CALL cp_fm_create(fm_prec, fm_struct)
2955 ALLOCATE (scaling(nao))
2956 nocc = nelec_spin(1)/2
2959 nocc = nelec_spin(ispin)
2965 IF (xas_tdp_control%n_excited > 0 .AND. xas_tdp_control%n_excited < nguess)
THEN
2966 nguess = xas_tdp_control%n_excited/nspins
2967 ELSE IF (xas_tdp_control%e_range > 0.0_dp)
THEN
2968 nguess = count(evals(nocc + 1:nao) - evals(nocc + 1) <= xas_tdp_control%e_range)
2972 scaling(nocc + 1:nocc + nguess) = 100.0_dp
2974 shift = evals(nocc + 1) - 0.01_dp
2975 scaling(nocc + nguess:nao) = 1.0_dp/(evals(nocc + nguess:nao) - shift)
2977 scaling(1:nocc) = 1.0_dp
2980 CALL cp_fm_create(work_fm, fm_struct)
2982 CALL cp_fm_copy_general(evecs, work_fm, para_env)
2983 CALL cp_fm_column_scale(work_fm, scaling)
2985 CALL parallel_gemm(
'N',
'T', nao, nao, nao, 1.0_dp, work_fm, evecs, 0.0_dp, fm_prec)
2988 ALLOCATE (xas_tdp_env%ot_prec(ispin)%matrix)
2989 CALL dbcsr_create(xas_tdp_env%ot_prec(ispin)%matrix, template=matrix_s(1)%matrix, name=
"OT_PREC")
2990 CALL copy_fm_to_dbcsr(fm_prec, xas_tdp_env%ot_prec(ispin)%matrix)
2991 CALL dbcsr_filter(xas_tdp_env%ot_prec(ispin)%matrix, xas_tdp_control%eps_filter)
2993 CALL cp_fm_release(work_fm)
2994 CALL cp_fm_release(fm_prec)
2996 CALL timestop(handle)
2998 END SUBROUTINE build_ot_spin_prec
3007 SUBROUTINE print_xps(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
3009 TYPE(donor_state_type),
POINTER :: donor_state
3010 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
3011 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
3012 TYPE(qs_environment_type),
POINTER :: qs_env
3014 INTEGER :: ido_mo, ispin, nspins, output_unit
3015 REAL(dp),
ALLOCATABLE,
DIMENSION(:, :) :: ips, soc_shifts
3017 output_unit = cp_logger_get_default_io_unit()
3019 nspins = 1;
IF (xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks) nspins = 2
3021 ALLOCATE (ips(
SIZE(donor_state%gw2x_evals, 1),
SIZE(donor_state%gw2x_evals, 2)))
3022 ips(:, :) = donor_state%gw2x_evals(:, :)
3025 IF (.NOT. xas_tdp_control%is_periodic)
THEN
3028 IF (donor_state%ndo_mo > 1)
THEN
3029 CALL get_soc_splitting(soc_shifts, donor_state, xas_tdp_env, xas_tdp_control, qs_env)
3030 ips(:, :) = ips(:, :) + soc_shifts
3032 IF (output_unit > 0)
THEN
3033 WRITE (output_unit, fmt=
"(/,T5,A,F23.6)") &
3034 "Ionization potentials for XPS (GW2X + SOC): ", -ips(1, 1)*evolt
3036 DO ispin = 1, nspins
3037 DO ido_mo = 1, donor_state%ndo_mo
3039 IF (ispin == 1 .AND. ido_mo == 1) cycle
3041 WRITE (output_unit, fmt=
"(T5,A,F23.6)") &
3042 " ", -ips(ido_mo, ispin)*evolt
3051 IF (output_unit > 0)
THEN
3052 WRITE (output_unit, fmt=
"(/,T5,A,F29.6)") &
3053 "Ionization potentials for XPS (GW2X): ", -ips(1, 1)*evolt
3055 IF (nspins == 2)
THEN
3056 WRITE (output_unit, fmt=
"(T5,A,F29.6)") &
3057 " ", -ips(1, 2)*evolt
3064 END SUBROUTINE print_xps
3073 SUBROUTINE print_xas_tdp_to_file(donor_state, xas_tdp_env, xas_tdp_control, xas_tdp_section)
3075 TYPE(donor_state_type),
POINTER :: donor_state
3076 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
3077 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
3078 TYPE(section_vals_type),
POINTER :: xas_tdp_section
3080 INTEGER :: i, output_unit, xas_tdp_unit
3081 TYPE(cp_logger_type),
POINTER :: logger
3084 logger => cp_get_default_logger()
3086 xas_tdp_unit = cp_print_key_unit_nr(logger, xas_tdp_section,
"PRINT%SPECTRUM", &
3087 extension=
".spectrum", file_position=
"APPEND", &
3088 file_action=
"WRITE", file_form=
"FORMATTED")
3090 output_unit = cp_logger_get_default_io_unit()
3092 IF (output_unit > 0)
THEN
3093 WRITE (output_unit, fmt=
"(/,T5,A,/)") &
3094 "Calculations done: "
3097 IF (xas_tdp_control%do_spin_cons)
THEN
3098 IF (xas_tdp_unit > 0)
THEN
3101 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3102 "==================================================================================", &
3103 "XAS TDP open-shell spin-conserving (no SOC) excitations for DONOR STATE: ", &
3104 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3105 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3106 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3107 "=================================================================================="
3111 IF (xas_tdp_control%do_quad)
THEN
3112 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3113 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3114 DO i = 1,
SIZE(donor_state%sc_evals)
3115 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3116 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4), &
3117 donor_state%quad_osc_str(i)
3119 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3120 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3121 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3122 DO i = 1,
SIZE(donor_state%sc_evals)
3123 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3124 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4), &
3125 donor_state%osc_str(i, 1), donor_state%osc_str(i, 2), donor_state%osc_str(i, 3)
3127 ELSE IF (xas_tdp_control%spin_dip)
THEN
3128 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3129 " Index Excitation energy (eV) fosc dipole (a.u.) alpha-comp beta-comp"
3130 DO i = 1,
SIZE(donor_state%sc_evals)
3131 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6)") &
3132 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4), &
3133 donor_state%alpha_osc(i, 4), donor_state%beta_osc(i, 4)
3136 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3137 " Index Excitation energy (eV) fosc dipole (a.u.)"
3138 DO i = 1,
SIZE(donor_state%sc_evals)
3139 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3140 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4)
3144 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3147 IF (output_unit > 0)
THEN
3148 WRITE (output_unit, fmt=
"(T5,A,F17.6)") &
3149 "First spin-conserving XAS excitation energy (eV): ", donor_state%sc_evals(1)*evolt
3154 IF (xas_tdp_control%do_spin_flip)
THEN
3155 IF (xas_tdp_unit > 0)
THEN
3158 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3159 "==================================================================================", &
3160 "XAS TDP open-shell spin-flip (no SOC) excitations for DONOR STATE: ", &
3161 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3162 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3163 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3164 "=================================================================================="
3168 IF (xas_tdp_control%do_quad)
THEN
3169 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3170 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3171 DO i = 1,
SIZE(donor_state%sf_evals)
3172 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3173 i, donor_state%sf_evals(i)*evolt, 0.0_dp, 0.0_dp
3175 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3176 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3177 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3178 DO i = 1,
SIZE(donor_state%sf_evals)
3179 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3180 i, donor_state%sf_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp
3182 ELSE IF (xas_tdp_control%spin_dip)
THEN
3183 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3184 " Index Excitation energy (eV) fosc dipole (a.u.) alpha-comp beta-comp"
3185 DO i = 1,
SIZE(donor_state%sf_evals)
3186 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6)") &
3187 i, donor_state%sf_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp
3190 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3191 " Index Excitation energy (eV) fosc dipole (a.u.)"
3192 DO i = 1,
SIZE(donor_state%sf_evals)
3193 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3194 i, donor_state%sf_evals(i)*evolt, 0.0_dp
3198 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3201 IF (output_unit > 0)
THEN
3202 WRITE (output_unit, fmt=
"(T5,A,F23.6)") &
3203 "First spin-flip XAS excitation energy (eV): ", donor_state%sf_evals(1)*evolt
3207 IF (xas_tdp_control%do_singlet)
THEN
3208 IF (xas_tdp_unit > 0)
THEN
3211 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3212 "==================================================================================", &
3213 "XAS TDP singlet excitations (no SOC) for DONOR STATE: ", &
3214 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3215 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3216 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3217 "=================================================================================="
3221 IF (xas_tdp_control%do_quad)
THEN
3222 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3223 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3224 DO i = 1,
SIZE(donor_state%sg_evals)
3225 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3226 i, donor_state%sg_evals(i)*evolt, donor_state%osc_str(i, 4), &
3227 donor_state%quad_osc_str(i)
3229 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3230 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3231 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3232 DO i = 1,
SIZE(donor_state%sg_evals)
3233 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3234 i, donor_state%sg_evals(i)*evolt, donor_state%osc_str(i, 4), &
3235 donor_state%osc_str(i, 1), donor_state%osc_str(i, 2), donor_state%osc_str(i, 3)
3238 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3239 " Index Excitation energy (eV) fosc dipole (a.u.)"
3240 DO i = 1,
SIZE(donor_state%sg_evals)
3241 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3242 i, donor_state%sg_evals(i)*evolt, donor_state%osc_str(i, 4)
3246 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3249 IF (output_unit > 0)
THEN
3250 WRITE (output_unit, fmt=
"(T5,A,F25.6)") &
3251 "First singlet XAS excitation energy (eV): ", donor_state%sg_evals(1)*evolt
3255 IF (xas_tdp_control%do_triplet)
THEN
3256 IF (xas_tdp_unit > 0)
THEN
3259 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3260 "==================================================================================", &
3261 "XAS TDP triplet excitations (no SOC) for DONOR STATE: ", &
3262 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3263 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3264 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3265 "=================================================================================="
3269 IF (xas_tdp_control%do_quad)
THEN
3270 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3271 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3272 DO i = 1,
SIZE(donor_state%tp_evals)
3273 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3274 i, donor_state%tp_evals(i)*evolt, 0.0_dp, 0.0_dp
3276 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3277 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3278 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3279 DO i = 1,
SIZE(donor_state%tp_evals)
3280 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3281 i, donor_state%tp_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp
3283 ELSE IF (xas_tdp_control%spin_dip)
THEN
3284 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3285 " Index Excitation energy (eV) fosc dipole (a.u.) alpha-comp beta-comp"
3286 DO i = 1,
SIZE(donor_state%tp_evals)
3287 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6)") &
3288 i, donor_state%tp_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp
3291 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3292 " Index Excitation energy (eV) fosc dipole (a.u.)"
3293 DO i = 1,
SIZE(donor_state%tp_evals)
3294 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3295 i, donor_state%tp_evals(i)*evolt, 0.0_dp
3299 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3302 IF (output_unit > 0)
THEN
3303 WRITE (output_unit, fmt=
"(T5,A,F25.6)") &
3304 "First triplet XAS excitation energy (eV): ", donor_state%tp_evals(1)*evolt
3308 IF (xas_tdp_control%do_soc .AND. donor_state%state_type == xas_2p_type)
THEN
3309 IF (xas_tdp_unit > 0)
THEN
3312 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3313 "==================================================================================", &
3314 "XAS TDP excitations after spin-orbit coupling for DONOR STATE: ", &
3315 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3316 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3317 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3318 "=================================================================================="
3321 IF (xas_tdp_control%do_quad)
THEN
3322 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3323 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3324 DO i = 1,
SIZE(donor_state%soc_evals)
3325 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3326 i, donor_state%soc_evals(i)*evolt, donor_state%soc_osc_str(i, 4), &
3327 donor_state%soc_quad_osc_str(i)
3329 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3330 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3331 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3332 DO i = 1,
SIZE(donor_state%soc_evals)
3333 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3334 i, donor_state%soc_evals(i)*evolt, donor_state%soc_osc_str(i, 4), &
3335 donor_state%soc_osc_str(i, 1), donor_state%soc_osc_str(i, 2), donor_state%soc_osc_str(i, 3)
3338 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3339 " Index Excitation energy (eV) fosc dipole (a.u.)"
3340 DO i = 1,
SIZE(donor_state%soc_evals)
3341 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3342 i, donor_state%soc_evals(i)*evolt, donor_state%soc_osc_str(i, 4)
3346 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3349 IF (output_unit > 0)
THEN
3350 WRITE (output_unit, fmt=
"(T5,A,F29.6)") &
3351 "First SOC XAS excitation energy (eV): ", donor_state%soc_evals(1)*evolt
3355 CALL cp_print_key_finished_output(xas_tdp_unit, logger, xas_tdp_section,
"PRINT%SPECTRUM")
3357 END SUBROUTINE print_xas_tdp_to_file
3367 SUBROUTINE write_donor_state_restart(ex_type, donor_state, xas_tdp_section, qs_env)
3369 INTEGER,
INTENT(IN) :: ex_type
3370 TYPE(donor_state_type),
POINTER :: donor_state
3371 TYPE(section_vals_type),
POINTER :: xas_tdp_section
3372 TYPE(qs_environment_type),
POINTER :: qs_env
3374 CHARACTER(len=*),
PARAMETER :: routinen =
'write_donor_state_restart'
3376 CHARACTER(len=default_path_length) :: filename
3377 CHARACTER(len=default_string_length) :: domo, excite, my_middle
3378 INTEGER :: ex_atom, handle, ispin, nao, ndo_mo, &
3379 nex, nspins, output_unit, rst_unit, &
3381 INTEGER,
DIMENSION(:, :),
POINTER :: mo_indices
3383 REAL(dp),
DIMENSION(:),
POINTER :: lr_evals
3384 TYPE(cp_fm_type),
POINTER :: lr_coeffs
3385 TYPE(cp_logger_type),
POINTER :: logger
3386 TYPE(mo_set_type),
DIMENSION(:),
POINTER :: mos
3387 TYPE(section_vals_type),
POINTER :: print_key
3389 NULLIFY (logger, lr_coeffs, lr_evals, print_key, mos)
3392 logger => cp_get_default_logger()
3394 IF (btest(cp_print_key_should_output(logger%iter_info, xas_tdp_section, &
3395 "PRINT%RESTART", used_print_key=print_key), cp_p_file)) do_print = .true.
3397 IF (.NOT. do_print)
RETURN
3399 CALL timeset(routinen, handle)
3401 output_unit = cp_logger_get_default_io_unit()
3404 SELECT CASE (ex_type)
3405 CASE (tddfpt_spin_cons)
3406 lr_evals => donor_state%sc_evals
3407 lr_coeffs => donor_state%sc_coeffs
3410 CASE (tddfpt_spin_flip)
3411 lr_evals => donor_state%sf_evals
3412 lr_coeffs => donor_state%sf_coeffs
3415 CASE (tddfpt_singlet)
3416 lr_evals => donor_state%sg_evals
3417 lr_coeffs => donor_state%sg_coeffs
3420 CASE (tddfpt_triplet)
3421 lr_evals => donor_state%tp_evals
3422 lr_coeffs => donor_state%tp_coeffs
3427 SELECT CASE (donor_state%state_type)
3436 ndo_mo = donor_state%ndo_mo
3437 nex =
SIZE(lr_evals)
3438 CALL cp_fm_get_info(lr_coeffs, nrow_global=nao)
3439 state_type = donor_state%state_type
3440 ex_atom = donor_state%at_index
3441 mo_indices => donor_state%mo_indices
3445 my_middle =
'xasat'//trim(adjustl(cp_to_string(ex_atom)))//
'_'//trim(domo)//
'_'//trim(excite)
3446 rst_unit = cp_print_key_unit_nr(logger, xas_tdp_section,
"PRINT%RESTART", extension=
".rst", &
3447 file_status=
"REPLACE", file_action=
"WRITE", &
3448 file_form=
"UNFORMATTED", middle_name=trim(my_middle))
3450 filename = cp_print_key_generate_filename(logger, print_key, middle_name=trim(my_middle), &
3451 extension=
".rst", my_local=.false.)
3453 IF (output_unit > 0)
THEN
3454 WRITE (unit=output_unit, fmt=
"(/,T5,A,/T5,A,A,A)") &
3455 "Linear-response orbitals and excitation energies are written in: ", &
3456 '"', trim(filename),
'"'
3460 IF (rst_unit > 0)
THEN
3461 WRITE (rst_unit) ex_atom, state_type, ndo_mo, ex_type
3462 WRITE (rst_unit) nao, nex, nspins
3463 WRITE (rst_unit) mo_indices(:, :)
3464 WRITE (rst_unit) lr_evals(:)
3466 CALL cp_fm_write_unformatted(lr_coeffs, rst_unit)
3469 CALL get_qs_env(qs_env, mos=mos)
3470 DO ispin = 1, nspins
3471 CALL cp_fm_write_unformatted(mos(ispin)%mo_coeff, rst_unit)
3475 CALL cp_print_key_finished_output(rst_unit, logger, xas_tdp_section,
"PRINT%RESTART")
3477 CALL timestop(handle)
3479 END SUBROUTINE write_donor_state_restart
3488 SUBROUTINE read_donor_state_restart(donor_state, ex_type, filename, qs_env)
3490 TYPE(donor_state_type),
POINTER :: donor_state
3491 INTEGER,
INTENT(OUT) :: ex_type
3492 CHARACTER(len=*),
INTENT(IN) :: filename
3493 TYPE(qs_environment_type),
POINTER :: qs_env
3495 CHARACTER(len=*),
PARAMETER :: routinen =
'read_donor_state_restart'
3497 INTEGER :: handle, ispin, nao, nex, nspins, &
3498 output_unit, read_params(7), rst_unit
3499 INTEGER,
DIMENSION(:, :),
POINTER :: mo_indices
3500 LOGICAL :: file_exists
3501 REAL(dp),
DIMENSION(:),
POINTER :: lr_evals
3502 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
3503 TYPE(cp_fm_struct_type),
POINTER :: fm_struct
3504 TYPE(cp_fm_type),
POINTER :: lr_coeffs
3505 TYPE(mo_set_type),
DIMENSION(:),
POINTER :: mos
3506 TYPE(mp_comm_type) :: group
3507 TYPE(mp_para_env_type),
POINTER :: para_env
3509 NULLIFY (lr_evals, lr_coeffs, para_env, fm_struct, blacs_env, mos)
3511 CALL timeset(routinen, handle)
3513 output_unit = cp_logger_get_default_io_unit()
3514 cpassert(
ASSOCIATED(donor_state))
3515 CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
3518 file_exists = .false.
3521 IF (para_env%is_source())
THEN
3523 INQUIRE (file=filename, exist=file_exists)
3524 IF (.NOT. file_exists) cpabort(
"Trying to read non-existing XAS_TDP restart file")
3526 CALL open_file(file_name=trim(filename), file_action=
"READ", file_form=
"UNFORMATTED", &
3527 file_position=
"REWIND", file_status=
"OLD", unit_number=rst_unit)
3530 IF (output_unit > 0)
THEN
3531 WRITE (unit=output_unit, fmt=
"(/,T5,A,/,T5,A,A,A)") &
3532 "Reading linear-response orbitals and excitation energies from file: ", &
3537 IF (rst_unit > 0)
THEN
3538 READ (rst_unit) read_params(1:4)
3539 READ (rst_unit) read_params(5:7)
3541 CALL group%bcast(read_params)
3542 donor_state%at_index = read_params(1)
3543 donor_state%state_type = read_params(2)
3544 donor_state%ndo_mo = read_params(3)
3545 ex_type = read_params(4)
3546 nao = read_params(5)
3547 nex = read_params(6)
3548 nspins = read_params(7)
3550 ALLOCATE (mo_indices(donor_state%ndo_mo, nspins))
3551 IF (rst_unit > 0)
THEN
3552 READ (rst_unit) mo_indices(1:donor_state%ndo_mo, 1:nspins)
3554 CALL group%bcast(mo_indices)
3555 donor_state%mo_indices => mo_indices
3558 ALLOCATE (lr_evals(nex))
3559 IF (rst_unit > 0)
READ (rst_unit) lr_evals(1:nex)
3560 CALL group%bcast(lr_evals)
3563 CALL cp_fm_struct_create(fm_struct, context=blacs_env, para_env=para_env, &
3564 nrow_global=nao, ncol_global=nex*donor_state%ndo_mo*nspins)
3565 ALLOCATE (lr_coeffs)
3566 CALL cp_fm_create(lr_coeffs, fm_struct)
3567 CALL cp_fm_read_unformatted(lr_coeffs, rst_unit)
3568 CALL cp_fm_struct_release(fm_struct)
3571 CALL get_qs_env(qs_env, mos=mos)
3572 DO ispin = 1, nspins
3573 CALL cp_fm_read_unformatted(mos(ispin)%mo_coeff, rst_unit)
3577 IF (para_env%is_source())
THEN
3578 CALL close_file(unit_number=rst_unit)
3582 SELECT CASE (ex_type)
3583 CASE (tddfpt_spin_cons)
3584 donor_state%sc_evals => lr_evals
3585 donor_state%sc_coeffs => lr_coeffs
3586 CASE (tddfpt_spin_flip)
3587 donor_state%sf_evals => lr_evals
3588 donor_state%sf_coeffs => lr_coeffs
3589 CASE (tddfpt_singlet)
3590 donor_state%sg_evals => lr_evals
3591 donor_state%sg_coeffs => lr_coeffs
3592 CASE (tddfpt_triplet)
3593 donor_state%tp_evals => lr_evals
3594 donor_state%tp_coeffs => lr_coeffs
3597 CALL timestop(handle)
3599 END SUBROUTINE read_donor_state_restart
3607 SUBROUTINE restart_calculation(rst_filename, xas_tdp_section, qs_env)
3609 CHARACTER(len=*),
INTENT(IN) :: rst_filename
3610 TYPE(section_vals_type),
POINTER :: xas_tdp_section
3611 TYPE(qs_environment_type),
POINTER :: qs_env
3614 TYPE(donor_state_type),
POINTER :: donor_state
3615 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
3617 NULLIFY (xas_tdp_env, donor_state)
3620 ALLOCATE (donor_state)
3621 CALL donor_state_create(donor_state)
3622 CALL read_donor_state_restart(donor_state, ex_type, rst_filename, qs_env)
3625 CALL xas_tdp_env_create(xas_tdp_env)
3626 CALL xas_tdp_post(ex_type, donor_state, xas_tdp_env, xas_tdp_section, qs_env)
3629 CALL xas_tdp_env_release(xas_tdp_env)
3630 CALL free_ds_memory(donor_state)
3631 DEALLOCATE (donor_state%mo_indices)
3632 DEALLOCATE (donor_state)
3634 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, matrix_vhxc, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Calculate the interaction radii for the operator matrix calculation.
subroutine, public init_interaction_radii_orb_basis(orb_basis_set, eps_pgf_orb, eps_pgf_short)
...
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, cneo_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, hund_j, u_of_dft_plus_u, j_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, j0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, proj_shell_charge, lr_atom, do_mtlr, u_j_loop, ao_coef, init_u_ramping_each_scf, reltmat, ghost, monovalent, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
Driver for the localization that should be general for all the methods available and all the definiti...
subroutine, public qs_loc_driver(qs_env, qs_loc_env, print_loc_section, myspin, ext_mo_coeff)
set up the calculation of localized orbitals
Driver for the localization that should be general for all the methods available and all the definiti...
subroutine, public qs_print_cubes(qs_env, mo_coeff, nstates, state_list, centers, print_key, root, ispin, idir, state0, file_position)
write the cube files for a set of selected states
subroutine, public centers_spreads_berry(qs_loc_env, nmoloc, cell, weights, ispin, print_loc_section, zij, c_zij, only_initial_out)
...
New version of the module for the localization of the molecular orbitals This should be able to use d...
subroutine, public localized_wfn_control_create(localized_wfn_control)
create the localized_wfn_control_type
subroutine, public qs_loc_env_release(qs_loc_env)
...
subroutine, public get_qs_loc_env(qs_loc_env, cell, local_molecules, localized_wfn_control, moloc_coeff, op_sm_set, op_fm_set, para_env, particle_set, weights, dim_op)
...
subroutine, public qs_loc_env_create(qs_loc_env)
...
Some utilities for the construction of the localization environment.
subroutine, public qs_loc_env_init(qs_loc_env, localized_wfn_control, qs_env, myspin, do_localize, loc_coeff, mo_loc_history)
allocates the data, and initializes the operators
subroutine, public set_loc_centers(localized_wfn_control, nmoloc, nspins)
create the center and spread array and the file names for the output
subroutine, public qs_loc_control_init(qs_loc_env, loc_section, do_homo, do_mixed, do_xas, nloc_xas, spin_xas)
initializes everything needed for localization of the HOMOs
Definition and initialisation of the mo data type.
subroutine, public write_mo_set_low(mo_array, qs_kind_set, particle_set, ires, rt_mos, matrix_ks)
...
collects routines that perform operations directly related to MOs
Definition and initialisation of the mo data type.
subroutine, public duplicate_mo_set(mo_set_new, mo_set_old)
allocate a new mo_set, and copy the old data
subroutine, public init_mo_set(mo_set, fm_pool, fm_ref, fm_struct, name, counter)
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 build_lin_mom_matrix(qs_env, matrix, minimum_image)
Calculation of the linear momentum matrix <mu|∂|nu> over Cartesian Gaussian functions.
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_curve)
Compute and write projected density of states.
module that contains the definitions of the scf types
integer, parameter, public ot_method_nr
Define Resonant Inelastic XRAY Scattering (RIXS) control type and associated create,...
All kind of helpful little routines.
pure integer function, public locate(array, x)
Purpose: Given an array array(1:n), and given a value x, a value x_index is returned which is the ind...
pure integer function, dimension(2), public get_limit(m, n, me)
divide m entries into n parts, return size of part me
driver for the xas calculation and xas_scf for the tp method
subroutine, public calc_stogto_overlap(base_a, base_b, matrix)
...
This module deals with all the integrals done on local atomic grids in xas_tdp. This is mostly used t...
subroutine, public init_xas_atom_env(xas_atom_env, xas_tdp_env, xas_tdp_control, qs_env, ltddfpt)
Initializes a xas_atom_env type given the qs_enxas_atom_env, qs_envv.
subroutine, public integrate_soc_atoms(matrix_soc, xas_atom_env, qs_env, soc_atom_env)
Computes the SOC matrix elements with respect to the ORB basis set for each atomic kind and put them ...
subroutine, public integrate_fxc_atoms(int_fxc, xas_atom_env, xas_tdp_control, qs_env)
Integrate the xc kernel as a function of r on the atomic grids for the RI_XAS basis.
Second order perturbation correction to XAS_TDP spectra (i.e. shift)
subroutine, public gw2x_shift(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
Computes the ionization potential using the GW2X method of Shigeta et. al. The result cam be used for...
subroutine, public get_soc_splitting(soc_shifts, donor_state, xas_tdp_env, xas_tdp_control, qs_env)
We try to compute the spin-orbit splitting via perturbation theory. We keep it \ cheap by only inculd...
3-center integrals machinery for the XAS_TDP method
subroutine, public compute_ri_coulomb2_int(ex_kind, xas_tdp_env, xas_tdp_control, qs_env)
Computes the two-center Coulomb integral needed for the RI in kernel calculation. Stores the integral...
subroutine, public compute_ri_3c_coulomb(xas_tdp_env, qs_env)
Computes the RI Coulomb 3-center integrals (ab|c), where c is from the RI_XAS basis and centered on t...
subroutine, public compute_ri_exchange2_int(ex_kind, xas_tdp_env, xas_tdp_control, qs_env)
Computes the two-center Exchange integral needed for the RI in kernel calculation....
subroutine, public compute_ri_3c_exchange(ex_atoms, xas_tdp_env, xas_tdp_control, qs_env)
Computes the RI exchange 3-center integrals (ab|c), where c is from the RI_XAS basis and centered on ...
Methods for X-Ray absorption spectroscopy (XAS) using TDDFPT.
subroutine, public xas_tdp_init(xas_tdp_env, xas_tdp_control, qs_env, rixs_env)
Overall control and environment types initialization.
subroutine, public xas_tdp(qs_env, rixs_env)
Driver for XAS TDDFT calculations.
Define XAS TDP control type and associated create, release, etc subroutines, as well as XAS TDP envir...
subroutine, public xas_tdp_env_create(xas_tdp_env)
Creates a TDP XAS environment type.
subroutine, public xas_tdp_env_release(xas_tdp_env)
Releases the TDP XAS environment type.
subroutine, public donor_state_create(donor_state)
Creates a donor_state.
subroutine, public xas_tdp_control_release(xas_tdp_control)
Releases the xas_tdp_control_type.
subroutine, public xas_atom_env_create(xas_atom_env)
Creates a xas_atom_env type.
subroutine, public set_xas_tdp_env(xas_tdp_env, nex_atoms, nex_kinds)
Sets values of selected variables within the TDP XAS environment type.
subroutine, public free_ds_memory(donor_state)
Deallocate a donor_state's heavy attributes.
subroutine, public set_donor_state(donor_state, at_index, at_symbol, kind_index, state_type)
sets specified values of the donor state type
subroutine, public xas_tdp_control_create(xas_tdp_control)
Creates and initializes the xas_tdp_control_type.
subroutine, public free_exat_memory(xas_tdp_env, atom, end_of_batch)
Releases the memory heavy attribute of xas_tdp_env that are specific to the current excited atom.
subroutine, public xas_atom_env_release(xas_atom_env)
Releases the xas_atom_env type.
subroutine, public read_xas_tdp_control(xas_tdp_control, xas_tdp_section)
Reads the inputs and stores in xas_tdp_control_type.
Utilities for X-ray absorption spectroscopy using TDDFPT.
subroutine, public include_rcs_soc(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
Includes the SOC effects on the precomputed restricted closed-shell singlet and triplet excitations....
subroutine, public setup_xas_tdp_prob(donor_state, qs_env, xas_tdp_env, xas_tdp_control)
Builds the matrix that defines the XAS TDDFPT generalized eigenvalue problem to be solved for excitat...
subroutine, public solve_xas_tdp_prob(donor_state, xas_tdp_control, xas_tdp_env, qs_env, ex_type)
Solves the XAS TDP generalized eigenvalue problem omega*C = matrix_tdp*C using standard full diagonal...
subroutine, public include_os_soc(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
Includes the SOC effects on the precomputed spin-conserving and spin-flip excitations from an open-sh...
Writes information on XC functionals to output.
subroutine, public xc_write(iounit, xc_section, lsd)
...
stores some data used in wavefunction fitting
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
keeps the information about the structure of a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.
A type that holds controlling information for the calculation of the spread of wfn and the optimizati...
contains all the info needed by quickstep to calculate the spread of a selected set of orbitals and i...
Type containing informations about a single donor state.
a environment type that contains all the info needed for XAS_TDP atomic grid calculations
Type containing control information for TDP XAS calculations.
Type containing informations such as inputs and results for TDP XAS calculations.