147#include "./base/base_uses.f90"
152 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'xas_tdp_methods'
168 CHARACTER(len=*),
PARAMETER :: routinen =
'xas_tdp'
170 CHARACTER(default_string_length) :: rst_filename
171 INTEGER :: handle, n_rep, output_unit
172 LOGICAL :: do_restart
175 CALL timeset(routinen, handle)
178 NULLIFY (xas_tdp_section)
182 IF (output_unit > 0)
THEN
183 WRITE (unit=output_unit, fmt=
"(/,T3,A,/,T3,A,/,T3,A,/,T3,A,/)") &
184 "!===========================================================================!", &
186 "! Starting TDDFPT driven X-rays absorption spectroscopy calculations !", &
187 "!===========================================================================!"
205 IF (output_unit > 0)
THEN
206 WRITE (unit=output_unit, fmt=
"(/,T3,A)") &
207 "# This is a RESTART calculation for PDOS and/or CUBE printing"
210 CALL restart_calculation(rst_filename, xas_tdp_section, qs_env)
214 CALL xas_tdp_core(xas_tdp_section, qs_env)
217 IF (output_unit > 0)
THEN
218 WRITE (unit=output_unit, fmt=
"(/,T3,A,/,T3,A,/,T3,A,/)") &
219 "!===========================================================================!", &
220 "! End of TDDFPT driven X-rays absorption spectroscopy calculations !", &
221 "!===========================================================================!"
224 CALL timestop(handle)
233 SUBROUTINE xas_tdp_core(xas_tdp_section, qs_env)
238 CHARACTER(LEN=default_string_length) :: kind_name
239 INTEGER :: batch_size, bo(2), current_state_index, iat, iatom, ibatch, ikind, ispin, istate, &
240 nbatch, nex_atom, output_unit, tmp_index
241 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: batch_atoms, ex_atoms_of_kind
242 INTEGER,
DIMENSION(:),
POINTER :: atoms_of_kind
243 LOGICAL :: do_os, end_of_batch, unique
250 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
255 NULLIFY (xas_tdp_env, xas_tdp_control, atomic_kind_set, atoms_of_kind, current_state)
256 NULLIFY (xas_atom_env, dft_control, matrix_ks, admm_env, qs_kind_set, tmp_basis)
261 IF (output_unit > 0)
THEN
262 WRITE (unit=output_unit, fmt=
"(/,T3,A)") &
263 "# Create and initialize the XAS_TDP environment"
265 CALL get_qs_env(qs_env, dft_control=dft_control)
267 CALL print_info(output_unit, xas_tdp_control, qs_env)
269 IF (output_unit > 0)
THEN
270 IF (xas_tdp_control%check_only)
THEN
271 cpwarn(
"This is a CHECK_ONLY run for donor MOs verification")
276 IF (xas_tdp_control%do_loc)
THEN
277 IF (output_unit > 0)
THEN
278 WRITE (unit=output_unit, fmt=
"(/,T3,A,/)") &
279 "# Localizing core orbitals for better identification"
282 IF (xas_tdp_control%do_uks)
THEN
283 DO ispin = 1, dft_control%nspins
285 xas_tdp_control%print_loc_subsection, myspin=ispin)
289 xas_tdp_control%print_loc_subsection, myspin=1)
294 CALL find_mo_centers(xas_tdp_env, xas_tdp_control, qs_env)
297 CALL assign_mos_to_ex_atoms(xas_tdp_env, xas_tdp_control, qs_env)
300 IF (xas_tdp_control%do_loc)
THEN
301 IF (output_unit > 0)
THEN
302 WRITE (unit=output_unit, fmt=
"(/,T3,A,/,T5,A)") &
303 "# Diagonalize localized MOs wrt the KS matrix in the subspace of each excited", &
304 "atom for better donor state identification."
306 CALL diagonalize_assigned_mo_subset(xas_tdp_env, xas_tdp_control, qs_env)
308 CALL find_mo_centers(xas_tdp_env, xas_tdp_control, qs_env)
311 IF (output_unit > 0)
THEN
312 WRITE (unit=output_unit, fmt=
"(/,T3,A,I4,A,/)") &
313 "# Assign the relevant subset of the ", xas_tdp_control%n_search, &
314 " lowest energy MOs to excited atoms"
316 CALL write_mos_to_ex_atoms_association(xas_tdp_env, xas_tdp_control, qs_env)
319 IF (xas_tdp_control%check_only)
CALL print_checks(xas_tdp_env, xas_tdp_control, qs_env)
323 IF ((xas_tdp_control%do_xc .OR. xas_tdp_control%do_soc .OR. xas_tdp_control%do_gw2x) &
324 .AND. .NOT. xas_tdp_control%check_only)
THEN
326 IF (output_unit > 0 .AND. xas_tdp_control%do_xc)
THEN
327 WRITE (unit=output_unit, fmt=
"(/,T3,A,I4,A)") &
328 "# Integrating the xc kernel on the atomic grids ..."
334 do_os = xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks
336 IF (xas_tdp_control%do_xc .AND. (.NOT. xas_tdp_control%xps_only))
THEN
340 IF (xas_tdp_control%do_soc .OR. xas_tdp_control%do_gw2x)
THEN
348 IF ((.NOT. (xas_tdp_control%check_only .OR. xas_tdp_control%xps_only)) .AND. &
349 (xas_tdp_control%do_xc .OR. xas_tdp_control%do_coulomb))
THEN
350 IF (output_unit > 0)
THEN
351 WRITE (unit=output_unit, fmt=
"(/,T3,A,I4,A)") &
352 "# Computing the RI 3-center Coulomb integrals ..."
360 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
361 current_state_index = 1
364 DO ikind = 1,
SIZE(atomic_kind_set)
366 IF (xas_tdp_control%check_only)
EXIT
367 IF (.NOT. any(xas_tdp_env%ex_kind_indices == ikind)) cycle
369 CALL get_atomic_kind(atomic_kind=atomic_kind_set(ikind), name=kind_name, &
370 atom_list=atoms_of_kind)
374 IF (xas_tdp_control%do_hfx)
THEN
382 CALL get_ri_3c_batches(ex_atoms_of_kind, nbatch, batch_size, atoms_of_kind, xas_tdp_env)
383 nex_atom =
SIZE(ex_atoms_of_kind)
386 DO ibatch = 1, nbatch
388 bo =
get_limit(nex_atom, nbatch, ibatch - 1)
389 batch_size = bo(2) - bo(1) + 1
390 ALLOCATE (batch_atoms(batch_size))
392 DO iat = bo(1), bo(2)
394 batch_atoms(iatom) = ex_atoms_of_kind(iat)
399 IF (xas_tdp_control%do_hfx)
THEN
400 IF (output_unit > 0)
THEN
401 WRITE (unit=output_unit, fmt=
"(/,T3,A,I4,A,I4,A,I1,A,A)") &
402 "# Computing the RI 3-center Exchange integrals for batch ", ibatch,
"(/", nbatch,
") of ", &
403 batch_size,
" atoms of kind: ", trim(kind_name)
410 DO iat = 1, batch_size
411 iatom = batch_atoms(iat)
413 tmp_index =
locate(xas_tdp_env%ex_atom_indices, iatom)
417 IF (xas_tdp_control%dipole_form ==
xas_dip_len .OR. xas_tdp_control%do_quad)
THEN
418 CALL compute_lenrep_multipole(iatom, xas_tdp_env, xas_tdp_control, qs_env)
422 DO istate = 1,
SIZE(xas_tdp_env%state_types, 1)
424 IF (xas_tdp_env%state_types(istate, tmp_index) ==
xas_not_excited) cycle
426 current_state => xas_tdp_env%donor_states(current_state_index)
428 at_symbol=kind_name, kind_index=ikind, &
429 state_type=xas_tdp_env%state_types(istate, tmp_index))
432 IF (output_unit > 0)
THEN
433 WRITE (unit=output_unit, fmt=
"(/,T3,A,A2,A,I4,A,A,/)") &
434 "# Start of calculations for donor state of type ", &
435 xas_tdp_env%state_type_char(current_state%state_type),
" for atom", &
436 current_state%at_index,
" of kind ", trim(current_state%at_symbol)
441 CALL assign_mos_to_donor_state(current_state, xas_tdp_env, xas_tdp_control, qs_env)
444 CALL perform_mulliken_on_donor_state(current_state, qs_env)
447 IF (xas_tdp_control%do_gw2x)
THEN
448 CALL gw2x_shift(current_state, xas_tdp_env, xas_tdp_control, qs_env)
452 IF (.NOT. xas_tdp_control%xps_only)
THEN
455 IF (xas_tdp_control%do_spin_cons)
THEN
458 CALL compute_dipole_fosc(current_state, xas_tdp_control, xas_tdp_env)
459 IF (xas_tdp_control%do_quad)
CALL compute_quadrupole_fosc(current_state, &
460 xas_tdp_control, xas_tdp_env)
462 xas_tdp_section, qs_env)
463 CALL write_donor_state_restart(
tddfpt_spin_cons, current_state, xas_tdp_section, qs_env)
466 IF (xas_tdp_control%do_spin_flip)
THEN
471 xas_tdp_section, qs_env)
472 CALL write_donor_state_restart(
tddfpt_spin_flip, current_state, xas_tdp_section, qs_env)
475 IF (xas_tdp_control%do_singlet)
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_singlet, current_state, xas_tdp_section, qs_env)
486 IF (xas_tdp_control%do_triplet)
THEN
491 xas_tdp_section, qs_env)
492 CALL write_donor_state_restart(
tddfpt_triplet, current_state, xas_tdp_section, qs_env)
496 IF (xas_tdp_control%do_soc .AND. current_state%state_type ==
xas_2p_type)
THEN
497 IF (xas_tdp_control%do_singlet .AND. xas_tdp_control%do_triplet)
THEN
498 CALL include_rcs_soc(current_state, xas_tdp_env, xas_tdp_control, qs_env)
500 IF (xas_tdp_control%do_spin_cons .AND. xas_tdp_control%do_spin_flip)
THEN
501 CALL include_os_soc(current_state, xas_tdp_env, xas_tdp_control, qs_env)
506 CALL print_xas_tdp_to_file(current_state, xas_tdp_env, xas_tdp_control, xas_tdp_section)
508 IF (xas_tdp_control%do_gw2x)
CALL print_xps(current_state, xas_tdp_env, xas_tdp_control, qs_env)
513 current_state_index = current_state_index + 1
514 NULLIFY (current_state)
518 end_of_batch = .false.
519 IF (iat == batch_size) end_of_batch = .true.
522 DEALLOCATE (batch_atoms)
524 DEALLOCATE (ex_atoms_of_kind)
528 IF (dft_control%do_admm)
THEN
529 CALL get_qs_env(qs_env, matrix_ks=matrix_ks, admm_env=admm_env)
530 DO ispin = 1, dft_control%nspins
536 IF (xas_tdp_control%eps_pgf > 0.0_dp)
THEN
537 CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set)
538 DO ikind = 1,
SIZE(atomic_kind_set)
539 CALL get_qs_kind(qs_kind_set(ikind), basis_set=tmp_basis, basis_type=
"ORB")
548 END SUBROUTINE xas_tdp_core
562 CHARACTER(LEN=default_string_length) :: kind_name
563 INTEGER :: at_ind, i, ispin, j, k, kind_ind, &
564 n_donor_states, n_kinds, nao, &
565 nat_of_kind, natom, nex_atoms, &
566 nex_kinds, nmatch, nspins
567 INTEGER,
DIMENSION(2) :: homo, n_mo, n_moloc
568 INTEGER,
DIMENSION(:),
POINTER :: ind_of_kind
569 LOGICAL :: do_os, do_uks, unique
571 REAL(
dp),
DIMENSION(:),
POINTER :: mo_evals
576 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_ks, matrix_s, rho_ao
582 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
588 NULLIFY (xas_tdp_section, at_kind_set, ind_of_kind, dft_control, qs_kind_set, tmp_basis)
589 NULLIFY (qs_loc_env, loc_section, mos, particle_set, rho, rho_ao, mo_evals, cell)
590 NULLIFY (mo_coeff, matrix_ks, admm_env, dummy_section)
595 CALL get_qs_env(qs_env, dft_control=dft_control)
600 IF (dft_control%uks) xas_tdp_control%do_uks = .true.
601 IF (dft_control%roks) xas_tdp_control%do_roks = .true.
602 do_uks = xas_tdp_control%do_uks
603 do_os = do_uks .OR. xas_tdp_control%do_roks
612 nex_atoms =
SIZE(xas_tdp_control%list_ex_atoms)
614 ALLOCATE (xas_tdp_env%ex_atom_indices(nex_atoms))
615 ALLOCATE (xas_tdp_env%state_types(
SIZE(xas_tdp_control%state_types, 1), nex_atoms))
616 xas_tdp_env%ex_atom_indices = xas_tdp_control%list_ex_atoms
617 xas_tdp_env%state_types = xas_tdp_control%state_types
621 IF (any(xas_tdp_env%ex_atom_indices > natom))
THEN
622 cpabort(
"Invalid index for the ATOM_LIST keyword.")
626 ALLOCATE (xas_tdp_env%ex_kind_indices(nex_atoms))
627 xas_tdp_env%ex_kind_indices = 0
629 CALL get_qs_env(qs_env, particle_set=particle_set)
631 at_ind = xas_tdp_env%ex_atom_indices(i)
633 IF (all(abs(xas_tdp_env%ex_kind_indices - j) .NE. 0))
THEN
635 xas_tdp_env%ex_kind_indices(k) = j
640 CALL reallocate(xas_tdp_env%ex_kind_indices, 1, nex_kinds)
645 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=at_kind_set)
646 n_kinds =
SIZE(at_kind_set)
649 nex_kinds =
SIZE(xas_tdp_control%list_ex_kinds)
650 ALLOCATE (xas_tdp_env%ex_kind_indices(nex_kinds))
655 natom=nat_of_kind, kind_number=kind_ind)
656 IF (any(xas_tdp_control%list_ex_kinds == kind_name))
THEN
657 nex_atoms = nex_atoms + nat_of_kind
659 xas_tdp_env%ex_kind_indices(k) = kind_ind
663 ALLOCATE (xas_tdp_env%ex_atom_indices(nex_atoms))
664 ALLOCATE (xas_tdp_env%state_types(
SIZE(xas_tdp_control%state_types, 1), nex_atoms))
670 natom=nat_of_kind, atom_list=ind_of_kind)
672 IF (xas_tdp_control%list_ex_kinds(j) == kind_name)
THEN
673 xas_tdp_env%ex_atom_indices(nex_atoms + 1:nex_atoms + nat_of_kind) = ind_of_kind
674 DO k = 1,
SIZE(xas_tdp_control%state_types, 1)
675 xas_tdp_env%state_types(k, nex_atoms + 1:nex_atoms + nat_of_kind) = &
676 xas_tdp_control%state_types(k, j)
678 nex_atoms = nex_atoms + nat_of_kind
684 CALL set_xas_tdp_env(xas_tdp_env, nex_atoms=nex_atoms, nex_kinds=nex_kinds)
687 IF (nmatch .NE.
SIZE(xas_tdp_control%list_ex_kinds))
THEN
688 cpabort(
"Invalid kind(s) for the KIND_LIST keyword.")
694 CALL sort_unique(xas_tdp_env%ex_atom_indices, unique)
695 IF (.NOT. unique)
THEN
696 cpabort(
"Excited atoms not uniquely defined.")
701 IF (all(cell%perd == 0))
THEN
702 xas_tdp_control%is_periodic = .false.
703 ELSE IF (all(cell%perd == 1))
THEN
704 xas_tdp_control%is_periodic = .true.
706 cpabort(
"XAS TDP only implemented for full PBCs or non-PBCs")
711 ALLOCATE (xas_tdp_env%donor_states(n_donor_states))
712 DO i = 1, n_donor_states
717 IF (dft_control%do_admm)
THEN
718 CALL get_qs_env(qs_env, admm_env=admm_env, matrix_ks=matrix_ks)
720 DO ispin = 1, dft_control%nspins
726 IF (xas_tdp_control%eps_pgf > 0.0_dp)
THEN
727 CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set)
729 DO i = 1,
SIZE(qs_kind_set)
730 CALL get_qs_kind(qs_kind_set(i), basis_set=tmp_basis, basis_type=
"ORB")
732 CALL get_qs_kind(qs_kind_set(i), basis_set=tmp_basis, basis_type=
"RI_XAS")
740 CALL get_qs_env(qs_env, mos=mos, matrix_ks=matrix_ks)
741 nspins = 1;
IF (do_uks) nspins = 2
744 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, eigenvalues=mo_evals)
754 l_val=xas_tdp_control%do_loc)
757 xas_tdp_control%loc_subsection,
"PRINT")
759 ALLOCATE (xas_tdp_env%qs_loc_env)
761 qs_loc_env => xas_tdp_env%qs_loc_env
762 loc_section => xas_tdp_control%loc_subsection
765 CALL get_mo_set(mos(1), nmo=n_mo(1), homo=homo(1), nao=nao)
769 IF (do_os)
CALL get_mo_set(mos(2), nmo=n_mo(2), homo=homo(2))
770 IF (do_uks) nspins = 2
773 IF (xas_tdp_control%n_search < 0 .OR. xas_tdp_control%n_search > minval(homo)) &
774 xas_tdp_control%n_search = minval(homo)
776 nloc_xas=xas_tdp_control%n_search, spin_xas=1)
780 qs_loc_env%localized_wfn_control%nloc_states(2) = xas_tdp_control%n_search
781 qs_loc_env%localized_wfn_control%lu_bound_states(1, 2) = 1
782 qs_loc_env%localized_wfn_control%lu_bound_states(2, 2) = xas_tdp_control%n_search
786 qs_loc_env%localized_wfn_control%operator_type =
op_loc_berry
787 qs_loc_env%localized_wfn_control%max_iter = 25000
788 IF (.NOT. xas_tdp_control%do_loc)
THEN
789 qs_loc_env%localized_wfn_control%localization_method =
do_loc_none
791 n_moloc = qs_loc_env%localized_wfn_control%nloc_states
792 CALL set_loc_centers(qs_loc_env%localized_wfn_control, n_moloc, nspins)
795 qs_env, do_localize=.true.)
798 qs_env, do_localize=.true., myspin=1)
804 ALLOCATE (xas_tdp_env%mos_of_ex_atoms(xas_tdp_control%n_search, nex_atoms, nspins))
807 IF (do_os) nspins = 2
808 CALL get_qs_env(qs_env, rho=rho, matrix_s=matrix_s)
811 ALLOCATE (xas_tdp_env%q_projector(nspins))
812 ALLOCATE (xas_tdp_env%q_projector(1)%matrix)
813 CALL dbcsr_create(xas_tdp_env%q_projector(1)%matrix, name=
"Q PROJECTOR ALPHA", &
814 template=matrix_s(1)%matrix, matrix_type=dbcsr_type_no_symmetry)
816 ALLOCATE (xas_tdp_env%q_projector(2)%matrix)
817 CALL dbcsr_create(xas_tdp_env%q_projector(2)%matrix, name=
"Q PROJECTOR BETA", &
818 template=matrix_s(1)%matrix, matrix_type=dbcsr_type_no_symmetry)
822 fact = -0.5_dp;
IF (do_os) fact = -1.0_dp
823 CALL dbcsr_multiply(
'N',
'N', fact, matrix_s(1)%matrix, rho_ao(1)%matrix, 0.0_dp, &
824 xas_tdp_env%q_projector(1)%matrix, filter_eps=xas_tdp_control%eps_filter)
829 CALL dbcsr_multiply(
'N',
'N', fact, matrix_s(1)%matrix, rho_ao(2)%matrix, 0.0_dp, &
830 xas_tdp_env%q_projector(2)%matrix, filter_eps=xas_tdp_control%eps_filter)
836 ALLOCATE (xas_tdp_env%dipmat(3))
838 ALLOCATE (xas_tdp_env%dipmat(i)%matrix)
839 CALL dbcsr_copy(matrix_tmp, matrix_s(1)%matrix, name=
"XAS TDP dipole matrix")
840 IF (xas_tdp_control%dipole_form ==
xas_dip_vel)
THEN
841 CALL dbcsr_create(xas_tdp_env%dipmat(i)%matrix, template=matrix_s(1)%matrix, &
842 matrix_type=dbcsr_type_antisymmetric)
845 CALL dbcsr_create(xas_tdp_env%dipmat(i)%matrix, template=matrix_s(1)%matrix, &
846 matrix_type=dbcsr_type_symmetric)
847 CALL dbcsr_copy(xas_tdp_env%dipmat(i)%matrix, matrix_tmp)
849 CALL dbcsr_set(xas_tdp_env%dipmat(i)%matrix, 0.0_dp)
854 IF (xas_tdp_control%do_quad)
THEN
855 ALLOCATE (xas_tdp_env%quadmat(6))
857 ALLOCATE (xas_tdp_env%quadmat(i)%matrix)
858 CALL dbcsr_copy(xas_tdp_env%quadmat(i)%matrix, matrix_s(1)%matrix, name=
"XAS TDP quadrupole matrix")
859 CALL dbcsr_set(xas_tdp_env%quadmat(i)%matrix, 0.0_dp)
864 IF (xas_tdp_control%dipole_form ==
xas_dip_vel)
THEN
866 CALL p_xyz_ao(xas_tdp_env%dipmat, qs_env, minimum_image=.true.)
870 IF (xas_tdp_control%do_soc .OR. xas_tdp_control%do_gw2x)
THEN
871 ALLOCATE (xas_tdp_env%orb_soc(3))
873 ALLOCATE (xas_tdp_env%orb_soc(i)%matrix)
878 CALL safety_check(xas_tdp_control, qs_env)
884 IF (xas_tdp_control%do_ot .OR. xas_tdp_control%do_gw2x)
THEN
885 CALL make_lumo_guess(xas_tdp_env, xas_tdp_control, qs_env)
898 SUBROUTINE get_ri_3c_batches(ex_atoms_of_kind, nbatch, batch_size, atoms_of_kind, xas_tdp_env)
900 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(INOUT) :: ex_atoms_of_kind
901 INTEGER,
INTENT(OUT) :: nbatch
902 INTEGER,
INTENT(IN) :: batch_size
903 INTEGER,
DIMENSION(:),
INTENT(IN) :: atoms_of_kind
906 INTEGER :: iat, iatom, nex_atom
911 DO iat = 1,
SIZE(atoms_of_kind)
912 iatom = atoms_of_kind(iat)
913 IF (.NOT. any(xas_tdp_env%ex_atom_indices == iatom)) cycle
914 nex_atom = nex_atom + 1
917 ALLOCATE (ex_atoms_of_kind(nex_atom))
919 DO iat = 1,
SIZE(atoms_of_kind)
920 iatom = atoms_of_kind(iat)
921 IF (.NOT. any(xas_tdp_env%ex_atom_indices == iatom)) cycle
922 nex_atom = nex_atom + 1
923 ex_atoms_of_kind(nex_atom) = iatom
928 CALL rng_stream%shuffle(ex_atoms_of_kind(1:nex_atom))
930 nbatch = nex_atom/batch_size
931 IF (nbatch*batch_size .NE. nex_atom) nbatch = nbatch + 1
933 END SUBROUTINE get_ri_3c_batches
940 SUBROUTINE safety_check(xas_tdp_control, qs_env)
948 IF (xas_tdp_control%is_periodic .AND. xas_tdp_control%do_hfx &
950 cpabort(
"XAS TDP with Coulomb operator for exact exchange only supports non-periodic BCs")
954 IF (xas_tdp_control%do_roks .OR. xas_tdp_control%do_uks)
THEN
956 IF (.NOT. (xas_tdp_control%do_spin_cons .OR. xas_tdp_control%do_spin_flip))
THEN
957 cpabort(
"Need spin-conserving and/or spin-flip excitations for open-shell systems")
960 IF (xas_tdp_control%do_singlet .OR. xas_tdp_control%do_triplet)
THEN
961 cpabort(
"Singlet/triplet excitations only for restricted closed-shell systems")
964 IF (xas_tdp_control%do_soc .AND. .NOT. &
965 (xas_tdp_control%do_spin_flip .AND. xas_tdp_control%do_spin_cons))
THEN
967 cpabort(
"Both spin-conserving and spin-flip excitations are required for SOC")
971 IF (.NOT. (xas_tdp_control%do_singlet .OR. xas_tdp_control%do_triplet))
THEN
972 cpabort(
"Need singlet and/or triplet excitations for closed-shell systems")
975 IF (xas_tdp_control%do_spin_cons .OR. xas_tdp_control%do_spin_flip)
THEN
976 cpabort(
"Spin-conserving/spin-flip excitations only for open-shell systems")
979 IF (xas_tdp_control%do_soc .AND. .NOT. &
980 (xas_tdp_control%do_singlet .AND. xas_tdp_control%do_triplet))
THEN
982 cpabort(
"Both singlet and triplet excitations are needed for SOC")
987 IF (xas_tdp_control%do_soc .AND. xas_tdp_control%e_range > 0.0_dp)
THEN
988 cpwarn(
"Using E_RANGE and SOC together may lead to crashes, use N_EXCITED for safety.")
992 IF (.NOT. xas_tdp_control%tamm_dancoff)
THEN
994 IF (xas_tdp_control%do_spin_flip)
THEN
995 cpabort(
"Spin-flip kernel only implemented for Tamm-Dancoff approximation")
998 IF (xas_tdp_control%do_ot)
THEN
999 cpabort(
"OT diagonalization only available within the Tamm-Dancoff approximation")
1004 IF (xas_tdp_control%do_gw2x)
THEN
1005 IF (.NOT. xas_tdp_control%do_hfx)
THEN
1006 cpabort(
"GW2x requires the definition of the EXACT_EXCHANGE kernel")
1008 IF (.NOT. xas_tdp_control%do_loc)
THEN
1009 cpabort(
"GW2X requires the LOCALIZE keyword in DONOR_STATES")
1014 CALL get_qs_env(qs_env, dft_control=dft_control)
1015 IF (dft_control%do_admm)
THEN
1020 cpabort(
"XAS_TDP only compatible with ADMM purification NONE, CAUCHY_SUBSPACE and MO_DIAG")
1025 END SUBROUTINE safety_check
1033 SUBROUTINE print_info(ou, xas_tdp_control, qs_env)
1035 INTEGER,
INTENT(IN) :: ou
1045 NULLIFY (input, kernel_section, dft_control, matrix_s)
1047 CALL get_qs_env(qs_env, input=input, dft_control=dft_control, matrix_s=matrix_s)
1052 IF (ou .LE. 0)
RETURN
1055 IF (xas_tdp_control%do_uks)
THEN
1056 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1057 "XAS_TDP| Reference calculation: Unrestricted Kohn-Sham"
1058 ELSE IF (xas_tdp_control%do_roks)
THEN
1059 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1060 "XAS_TDP| Reference calculation: Restricted Open-Shell Kohn-Sham"
1062 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1063 "XAS_TDP| Reference calculation: Restricted Closed-Shell Kohn-Sham"
1067 IF (xas_tdp_control%tamm_dancoff)
THEN
1068 WRITE (unit=ou, fmt=
"(T3,A)") &
1069 "XAS_TDP| Tamm-Dancoff Approximation (TDA): On"
1071 WRITE (unit=ou, fmt=
"(T3,A)") &
1072 "XAS_TDP| Tamm-Dancoff Approximation (TDA): Off"
1076 IF (xas_tdp_control%dipole_form ==
xas_dip_vel)
THEN
1077 WRITE (unit=ou, fmt=
"(T3,A)") &
1078 "XAS_TDP| Transition Dipole Representation: VELOCITY"
1080 WRITE (unit=ou, fmt=
"(T3,A)") &
1081 "XAS_TDP| Transition Dipole Representation: LENGTH"
1085 IF (xas_tdp_control%do_quad)
THEN
1086 WRITE (unit=ou, fmt=
"(T3,A)") &
1087 "XAS_TDP| Transition Quadrupole: On"
1091 IF (xas_tdp_control%eps_pgf > 0.0_dp)
THEN
1092 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1093 "XAS_TDP| EPS_PGF_XAS: ", xas_tdp_control%eps_pgf
1095 WRITE (unit=ou, fmt=
"(T3,A,ES7.1,A)") &
1096 "XAS_TDP| EPS_PGF_XAS: ", dft_control%qs_control%eps_pgf_orb,
" (= EPS_PGF_ORB)"
1100 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1101 "XAS_TDP| EPS_FILTER: ", xas_tdp_control%eps_filter
1104 IF (xas_tdp_control%do_xc)
THEN
1105 WRITE (unit=ou, fmt=
"(T3,A)") &
1106 "XAS_TDP| Radial Grid(s) Info: Kind, na, nr"
1107 DO i = 1,
SIZE(xas_tdp_control%grid_info, 1)
1108 WRITE (unit=ou, fmt=
"(T3,A,A6,A,A,A,A)") &
1109 " ", trim(xas_tdp_control%grid_info(i, 1)),
", ", &
1110 trim(xas_tdp_control%grid_info(i, 2)),
", ", trim(xas_tdp_control%grid_info(i, 3))
1115 IF (.NOT. xas_tdp_control%do_coulomb)
THEN
1116 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1117 "XAS_TDP| No kernel (standard DFT)"
1121 IF (xas_tdp_control%do_xc)
THEN
1123 WRITE (unit=ou, fmt=
"(/,T3,A,F5.2,A)") &
1124 "XAS_TDP| RI Region's Radius: ", xas_tdp_control%ri_radius*
angstrom,
" Ang"
1126 WRITE (unit=ou, fmt=
"(T3,A,/)") &
1127 "XAS_TDP| XC Kernel Functional(s) used for the kernel:"
1130 CALL xc_write(ou, kernel_section, lsd=.true.)
1134 IF (xas_tdp_control%do_hfx)
THEN
1135 WRITE (unit=ou, fmt=
"(/,T3,A,/,/,T3,A,F5.3)") &
1136 "XAS_TDP| Exact Exchange Kernel: Yes ", &
1137 "EXACT_EXCHANGE| Scale: ", xas_tdp_control%sx
1139 WRITE (unit=ou, fmt=
"(T3,A)") &
1140 "EXACT_EXCHANGE| Potential : Coulomb"
1142 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,A)") &
1143 "EXACT_EXCHANGE| Potential: Truncated Coulomb", &
1144 "EXACT_EXCHANGE| Range: ", xas_tdp_control%x_potential%cutoff_radius*
angstrom,
", (Ang)", &
1145 "EXACT_EXCHANGE| T_C_G_DATA: ", trim(xas_tdp_control%x_potential%filename)
1147 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,F5.2,A,/,T3,A,ES7.1)") &
1148 "EXACT_EXCHANGE| Potential: Short Range", &
1149 "EXACT_EXCHANGE| Omega: ", xas_tdp_control%x_potential%omega,
", (1/a0)", &
1150 "EXACT_EXCHANGE| Effective Range: ", xas_tdp_control%x_potential%cutoff_radius*
angstrom,
", (Ang)", &
1151 "EXACT_EXCHANGE| EPS_RANGE: ", xas_tdp_control%eps_range
1153 IF (xas_tdp_control%eps_screen > 1.0e-16)
THEN
1154 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1155 "EXACT_EXCHANGE| EPS_SCREENING: ", xas_tdp_control%eps_screen
1159 IF (xas_tdp_control%do_ri_metric)
THEN
1161 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1162 "EXACT_EXCHANGE| Using a RI metric"
1163 IF (xas_tdp_control%ri_m_potential%potential_type ==
do_potential_id)
THEN
1164 WRITE (unit=ou, fmt=
"(T3,A)") &
1165 "EXACT_EXCHANGE RI_METRIC| Potential : Overlap"
1167 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,A)") &
1168 "EXACT_EXCHANGE RI_METRIC| Potential: Truncated Coulomb", &
1169 "EXACT_EXCHANGE RI_METRIC| Range: ", xas_tdp_control%ri_m_potential%cutoff_radius &
1171 "EXACT_EXCHANGE RI_METRIC| T_C_G_DATA: ", trim(xas_tdp_control%ri_m_potential%filename)
1173 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,F5.2,A,/,T3,A,ES7.1)") &
1174 "EXACT_EXCHANGE RI_METRIC| Potential: Short Range", &
1175 "EXACT_EXCHANGE RI_METRIC| Omega: ", xas_tdp_control%ri_m_potential%omega,
", (1/a0)", &
1176 "EXACT_EXCHANGE RI_METRIC| Effective Range: ", &
1177 xas_tdp_control%ri_m_potential%cutoff_radius*
angstrom,
", (Ang)", &
1178 "EXACT_EXCHANGE RI_METRIC| EPS_RANGE: ", xas_tdp_control%eps_range
1182 WRITE (unit=ou, fmt=
"(/,T3,A,/)") &
1183 "XAS_TDP| Exact Exchange Kernel: No "
1187 WRITE (unit=ou, fmt=
"(/,T3,A,F5.2)") &
1188 "XAS_TDP| Overlap matrix occupation: ", occ
1191 IF (xas_tdp_control%do_gw2x)
THEN
1192 WRITE (unit=ou, fmt=
"(T3,A,/)") &
1193 "XAS_TDP| GW2X correction enabled"
1195 IF (xas_tdp_control%xps_only)
THEN
1196 WRITE (unit=ou, fmt=
"(T3,A)") &
1197 "GW2X| Only computing ionizations potentials for XPS"
1200 IF (xas_tdp_control%pseudo_canonical)
THEN
1201 WRITE (unit=ou, fmt=
"(T3,A)") &
1202 "GW2X| Using the pseudo-canonical scheme"
1204 WRITE (unit=ou, fmt=
"(T3,A)") &
1205 "GW2X| Using the GW2X* scheme"
1208 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1209 "GW2X| EPS_GW2X: ", xas_tdp_control%gw2x_eps
1211 WRITE (unit=ou, fmt=
"(T3,A,I5)") &
1212 "GW2X| contraction batch size: ", xas_tdp_control%batch_size
1214 IF ((int(xas_tdp_control%c_os) .NE. 1) .OR. (int(xas_tdp_control%c_ss) .NE. 1))
THEN
1215 WRITE (unit=ou, fmt=
"(T3,A,F7.4,/,T3,A,F7.4)") &
1216 "GW2X| Same-spin scaling factor: ", xas_tdp_control%c_ss, &
1217 "GW2X| Opposite-spin scaling factor: ", xas_tdp_control%c_os
1222 END SUBROUTINE print_info
1237 SUBROUTINE assign_mos_to_ex_atoms(xas_tdp_env, xas_tdp_control, qs_env)
1243 INTEGER :: at_index, iat, iat_memo, imo, ispin, &
1244 n_atoms, n_search, nex_atoms, nspins
1245 INTEGER,
DIMENSION(3) :: perd_init
1246 INTEGER,
DIMENSION(:, :, :),
POINTER :: mos_of_ex_atoms
1247 REAL(
dp) :: dist, dist_min
1248 REAL(
dp),
DIMENSION(3) :: at_pos, r_ac, wfn_center
1253 NULLIFY (localized_wfn_control, mos_of_ex_atoms, cell, particle_set)
1256 mos_of_ex_atoms => xas_tdp_env%mos_of_ex_atoms
1257 mos_of_ex_atoms(:, :, :) = -1
1258 n_search = xas_tdp_control%n_search
1259 nex_atoms = xas_tdp_env%nex_atoms
1260 localized_wfn_control => xas_tdp_env%qs_loc_env%localized_wfn_control
1261 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, cell=cell)
1262 n_atoms =
SIZE(particle_set)
1263 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1266 perd_init = cell%perd
1270 DO ispin = 1, nspins
1271 DO imo = 1, n_search
1273 wfn_center(1:3) = localized_wfn_control%centers_set(ispin)%array(1:3, imo)
1277 dist_min = 10000.0_dp
1279 at_pos = particle_set(iat)%r
1280 r_ac =
pbc(at_pos, wfn_center, cell)
1284 IF (dist < dist_min)
THEN
1291 IF (any(xas_tdp_env%ex_atom_indices == iat_memo))
THEN
1292 at_index =
locate(xas_tdp_env%ex_atom_indices, iat_memo)
1293 mos_of_ex_atoms(imo, at_index, ispin) = 1
1299 cell%perd = perd_init
1301 END SUBROUTINE assign_mos_to_ex_atoms
1313 SUBROUTINE reinit_qs_loc_env(qs_loc_env, n_loc_states, do_uks, qs_env)
1316 INTEGER,
INTENT(IN) :: n_loc_states
1317 LOGICAL,
INTENT(IN) :: do_uks
1320 INTEGER :: i, nspins
1329 loc_wfn_control => qs_loc_env%localized_wfn_control
1334 loc_wfn_control%nloc_states(:) = n_loc_states
1335 loc_wfn_control%eps_occ = 0.0_dp
1336 loc_wfn_control%lu_bound_states(1, :) = 1
1337 loc_wfn_control%lu_bound_states(2, :) = n_loc_states
1339 loc_wfn_control%do_homo = .true.
1340 ALLOCATE (loc_wfn_control%loc_states(n_loc_states, 2))
1341 DO i = 1, n_loc_states
1342 loc_wfn_control%loc_states(i, :) = i
1345 nspins = 1;
IF (do_uks) nspins = 2
1346 CALL set_loc_centers(loc_wfn_control, loc_wfn_control%nloc_states, nspins=nspins)
1349 CALL qs_loc_env_init(qs_loc_env, loc_wfn_control, qs_env, do_localize=.true.)
1351 CALL qs_loc_env_init(qs_loc_env, loc_wfn_control, qs_env, myspin=1, do_localize=.true.)
1354 END SUBROUTINE reinit_qs_loc_env
1364 SUBROUTINE diagonalize_assigned_mo_subset(xas_tdp_env, xas_tdp_control, qs_env)
1370 INTEGER :: i, iat, ilmo, ispin, nao, nlmo, nspins
1371 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: evals
1374 TYPE(
cp_fm_type) :: evecs, ks_fm, lmo_fm, work
1380 NULLIFY (mos, mo_coeff, matrix_ks, para_env, blacs_env, lmo_struct, ks_struct)
1383 CALL get_qs_env(qs_env, mos=mos, matrix_ks=matrix_ks, para_env=para_env, blacs_env=blacs_env)
1385 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1388 DO ispin = 1, nspins
1389 DO iat = 1, xas_tdp_env%nex_atoms
1392 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, nao=nao)
1395 nlmo = count(xas_tdp_env%mos_of_ex_atoms(:, iat, ispin) == 1)
1397 para_env=para_env, context=blacs_env)
1402 para_env=para_env, context=blacs_env)
1408 DO ilmo = 1, xas_tdp_control%n_search
1409 IF (xas_tdp_env%mos_of_ex_atoms(ilmo, iat, ispin) == -1) cycle
1414 s_firstcol=ilmo, t_firstrow=1, t_firstcol=i)
1420 CALL parallel_gemm(
'T',
'N', nlmo, nlmo, nao, 1.0_dp, lmo_fm, work, 0.0_dp, ks_fm)
1423 ALLOCATE (evals(nlmo))
1428 CALL parallel_gemm(
'N',
'N', nao, nlmo, nlmo, 1.0_dp, lmo_fm, evecs, 0.0_dp, work)
1432 DO ilmo = 1, xas_tdp_control%n_search
1433 IF (xas_tdp_env%mos_of_ex_atoms(ilmo, iat, ispin) == -1) cycle
1437 s_firstcol=i, t_firstrow=1, t_firstcol=ilmo)
1451 END SUBROUTINE diagonalize_assigned_mo_subset
1462 SUBROUTINE assign_mos_to_donor_state(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
1469 INTEGER :: at_index, i, iat, imo, ispin, l, my_mo, &
1470 n_search, n_states, nao, ndo_so, nj, &
1471 nsgf_kind, nsgf_sto, nspins, &
1473 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: my_mos
1474 INTEGER,
DIMENSION(2) :: next_best_overlap_ind
1475 INTEGER,
DIMENSION(4, 7) :: ne
1476 INTEGER,
DIMENSION(:),
POINTER :: first_sgf, lq, nq
1477 INTEGER,
DIMENSION(:, :, :),
POINTER :: mos_of_ex_atoms
1480 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) ::
diag, overlap, sto_overlap
1481 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: max_overlap
1482 REAL(
dp),
DIMENSION(2) :: next_best_overlap
1483 REAL(
dp),
DIMENSION(:),
POINTER :: mo_evals, zeta
1484 REAL(
dp),
DIMENSION(:, :),
POINTER :: overlap_matrix, tmp_coeff
1488 TYPE(
cp_fm_type),
POINTER :: gs_coeffs, mo_coeff
1494 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
1497 NULLIFY (sto_basis_set, sto_to_gto_basis_set, qs_kind_set, kind_basis_set, lq, nq, zeta)
1498 NULLIFY (overlap_matrix, mos, mo_coeff, mos_of_ex_atoms, tmp_coeff, first_sgf, particle_set)
1499 NULLIFY (mo_evals, matrix_ks, para_env, blacs_env)
1500 NULLIFY (eval_mat_struct, gs_struct, gs_coeffs)
1504 CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set, mos=mos, particle_set=particle_set, &
1505 matrix_ks=matrix_ks, para_env=para_env, blacs_env=blacs_env)
1507 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1518 ELSE IF (donor_state%state_type ==
xas_2s_type)
THEN
1522 ELSE IF (donor_state%state_type ==
xas_2p_type)
THEN
1527 cpabort(
"Procedure for required type not implemented")
1529 ALLOCATE (my_mos(n_states, nspins))
1530 ALLOCATE (max_overlap(n_states, nspins))
1533 CALL get_qs_kind(qs_kind_set(donor_state%kind_index), zeff=zeff)
1541 ne(l, i) =
ptable(zval)%e_conv(l - 1) - 2*nj*(i - l)
1542 ne(l, i) = max(ne(l, i), 0)
1543 ne(l, i) = min(ne(l, i), 2*nj)
1548 zeta(1) =
srules(zval, ne, nq(1), lq(1))
1555 DEALLOCATE (nq, lq, zeta)
1559 gto_basis_set=sto_to_gto_basis_set, &
1561 sto_to_gto_basis_set%norm_type = 2
1565 CALL get_qs_kind(qs_kind_set(donor_state%kind_index), basis_set=kind_basis_set)
1570 ALLOCATE (overlap_matrix(nsgf_sto, nsgf_kind))
1580 mos_of_ex_atoms => xas_tdp_env%mos_of_ex_atoms
1581 n_search = xas_tdp_control%n_search
1582 at_index = donor_state%at_index
1583 iat =
locate(xas_tdp_env%ex_atom_indices, at_index)
1584 ALLOCATE (first_sgf(
SIZE(particle_set)))
1585 CALL get_particle_set(particle_set=particle_set, qs_kind_set=qs_kind_set, first_sgf=first_sgf)
1586 ALLOCATE (tmp_coeff(nsgf_kind, 1))
1587 ALLOCATE (sto_overlap(nsgf_kind))
1588 ALLOCATE (overlap(n_search))
1590 next_best_overlap = 0.0_dp
1591 max_overlap = 0.0_dp
1593 DO ispin = 1, nspins
1595 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, nao=nao)
1599 DO imo = 1, n_search
1600 IF (mos_of_ex_atoms(imo, iat, ispin) > 0)
THEN
1602 sto_overlap = 0.0_dp
1606 CALL cp_fm_get_submatrix(fm=mo_coeff, target_m=tmp_coeff, start_row=first_sgf(at_index), &
1607 start_col=imo, n_rows=nsgf_kind, n_cols=1, transpose=.false.)
1610 CALL dgemm(
'N',
'N', nsgf_sto, 1, nsgf_kind, 1.0_dp, overlap_matrix, nsgf_sto, &
1611 tmp_coeff, nsgf_kind, 0.0_dp, sto_overlap, nsgf_sto)
1616 overlap(imo) = sum(abs(sto_overlap))
1623 my_mo = maxloc(overlap, 1)
1624 my_mos(i, ispin) = my_mo
1625 max_overlap(i, ispin) = maxval(overlap, 1)
1626 overlap(my_mo) = 0.0_dp
1629 next_best_overlap(ispin) = maxval(overlap, 1)
1630 next_best_overlap_ind(ispin) = maxloc(overlap, 1)
1638 DEALLOCATE (overlap_matrix, tmp_coeff)
1641 IF (all(my_mos > 0) .AND. all(my_mos <= n_search))
THEN
1643 ALLOCATE (donor_state%mo_indices(n_states, nspins))
1644 donor_state%mo_indices = my_mos
1645 donor_state%ndo_mo = n_states
1649 para_env=para_env, context=blacs_env)
1650 ALLOCATE (donor_state%gs_coeffs)
1653 DO ispin = 1, nspins
1654 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff)
1657 ncol=1, s_firstrow=1, s_firstcol=my_mos(i, ispin), &
1658 t_firstrow=1, t_firstcol=(ispin - 1)*n_states + i)
1661 gs_coeffs => donor_state%gs_coeffs
1664 ALLOCATE (donor_state%contract_coeffs(nsgf_kind, n_states*nspins))
1665 CALL cp_fm_get_submatrix(gs_coeffs, donor_state%contract_coeffs, start_row=first_sgf(at_index), &
1666 start_col=1, n_rows=nsgf_kind, n_cols=n_states*nspins)
1671 IF (.NOT. xas_tdp_control%do_loc .AND. .NOT. xas_tdp_control%do_roks)
THEN
1672 IF (output_unit > 0)
THEN
1673 WRITE (unit=output_unit, fmt=
"(T5,A,/,T5,A,/,T5,A)") &
1674 "The following canonical MO(s) have been associated with the donor state(s)", &
1675 "based on the overlap with the components of a minimal STO basis: ", &
1676 " Spin MO index overlap(sum)"
1679 ALLOCATE (donor_state%energy_evals(n_states, nspins))
1680 donor_state%energy_evals = 0.0_dp
1683 DO ispin = 1, nspins
1684 CALL get_mo_set(mos(ispin), eigenvalues=mo_evals)
1686 donor_state%energy_evals(i, ispin) = mo_evals(my_mos(i, ispin))
1688 IF (output_unit > 0)
THEN
1689 WRITE (unit=output_unit, fmt=
"(T46,I4,I11,F17.5)") &
1690 ispin, my_mos(i, ispin), max_overlap(i, ispin)
1698 IF (output_unit > 0)
THEN
1699 WRITE (unit=output_unit, fmt=
"(T5,A,/,T5,A,/,T5,A)") &
1700 "The following localized MO(s) have been associated with the donor state(s)", &
1701 "based on the overlap with the components of a minimal STO basis: ", &
1702 " Spin MO index overlap(sum)"
1706 DO ispin = 1, nspins
1710 IF (output_unit > 0)
THEN
1711 WRITE (unit=output_unit, fmt=
"(T46,I4,I11,F17.5)") &
1712 ispin, my_mos(i, ispin), max_overlap(i, ispin)
1720 ndo_so = nspins*n_states
1723 para_env=para_env, context=blacs_env)
1725 ALLOCATE (
diag(ndo_so))
1727 IF (.NOT. xas_tdp_control%do_roks)
THEN
1729 ALLOCATE (donor_state%energy_evals(n_states, nspins))
1730 donor_state%energy_evals = 0.0_dp
1733 DO ispin = 1, nspins
1735 CALL parallel_gemm(
'T',
'N', ndo_so, ndo_so, nao, 1.0_dp, gs_coeffs, work_mat, 0.0_dp, eval_mat)
1739 donor_state%energy_evals(:, ispin) =
diag((ispin - 1)*n_states + 1:ispin*n_states)
1745 ALLOCATE (donor_state%energy_evals(n_states, 2))
1746 donor_state%energy_evals = 0.0_dp
1751 CALL parallel_gemm(
'T',
'N', ndo_so, ndo_so, nao, 1.0_dp, gs_coeffs, work_mat, 0.0_dp, eval_mat)
1754 donor_state%energy_evals(:, ispin) =
diag(:)
1769 ALLOCATE (donor_state%gw2x_evals(
SIZE(donor_state%energy_evals, 1),
SIZE(donor_state%energy_evals, 2)))
1770 donor_state%gw2x_evals(:, :) = donor_state%energy_evals(:, :)
1774 DEALLOCATE (first_sgf)
1776 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T5,A)")
" "
1778 DO ispin = 1, nspins
1779 IF (output_unit > 0)
THEN
1780 WRITE (unit=output_unit, fmt=
"(T5,A,I1,A,F7.5,A,I4)") &
1781 "The next best overlap for spin ", ispin,
" is ", next_best_overlap(ispin), &
1782 " for MO with index ", next_best_overlap_ind(ispin)
1785 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T5,A)")
" "
1788 cpabort(
"A core donor state could not be assigned MO(s). Increasing NSEARCH might help.")
1791 END SUBROUTINE assign_mos_to_donor_state
1801 SUBROUTINE find_mo_centers(xas_tdp_env, xas_tdp_control, qs_env)
1807 INTEGER :: dim_op, i, ispin, j, n_centers, nao, &
1809 REAL(
dp),
DIMENSION(6) :: weights
1814 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:, :) :: zij_fm_set
1815 TYPE(
cp_fm_type),
DIMENSION(:),
POINTER :: moloc_coeff
1817 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: op_sm_set
1822 NULLIFY (qs_loc_env, cell, print_loc_section, op_sm_set, moloc_coeff, vectors)
1823 NULLIFY (tmp_fm_struct, para_env, blacs_env, prog_run_info)
1826 print_loc_section => xas_tdp_control%print_loc_subsection
1827 n_centers = xas_tdp_control%n_search
1828 CALL get_qs_env(qs_env=qs_env, para_env=para_env, blacs_env=blacs_env, cell=cell)
1836 CALL reinit_qs_loc_env(xas_tdp_env%qs_loc_env, n_centers, xas_tdp_control%do_uks, qs_env)
1837 qs_loc_env => xas_tdp_env%qs_loc_env
1840 CALL get_qs_loc_env(qs_loc_env=qs_loc_env, weights=weights, op_sm_set=op_sm_set, &
1841 moloc_coeff=moloc_coeff)
1844 vectors => moloc_coeff(1)
1849 ncol_global=n_centers, nrow_global=n_centers)
1851 IF (cell%orthorhombic)
THEN
1856 ALLOCATE (zij_fm_set(2, dim_op))
1864 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1866 DO ispin = 1, nspins
1868 vectors => moloc_coeff(ispin)
1873 CALL parallel_gemm(
"T",
"N", n_centers, n_centers, nao, 1.0_dp, vectors, opvec, 0.0_dp, &
1880 cell=cell, weights=weights, ispin=ispin, &
1881 print_loc_section=print_loc_section, only_initial_out=.true.)
1890 qs_loc_env%do_localize = xas_tdp_control%do_loc
1892 END SUBROUTINE find_mo_centers
1901 SUBROUTINE print_checks(xas_tdp_env, xas_tdp_control, qs_env)
1907 CHARACTER(LEN=default_string_length) :: kind_name
1908 INTEGER :: current_state_index, iat, iatom, ikind, &
1909 istate, output_unit, tmp_index
1910 INTEGER,
DIMENSION(:),
POINTER :: atoms_of_kind
1914 NULLIFY (atomic_kind_set, atoms_of_kind, current_state)
1918 IF (output_unit > 0)
THEN
1919 WRITE (output_unit,
"(/,T3,A,/,T3,A,/,T3,A)") &
1920 "# Check the donor states for their quality. They need to have a well defined type ", &
1921 " (1s, 2s, etc) which is indicated by the overlap. They also need to be localized, ", &
1922 " for which the Mulliken population analysis is one indicator (must be close to 1.0)"
1926 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
1927 current_state_index = 1
1930 DO ikind = 1,
SIZE(atomic_kind_set)
1932 CALL get_atomic_kind(atomic_kind=atomic_kind_set(ikind), name=kind_name, &
1933 atom_list=atoms_of_kind)
1935 IF (.NOT. any(xas_tdp_env%ex_kind_indices == ikind)) cycle
1938 DO iat = 1,
SIZE(atoms_of_kind)
1939 iatom = atoms_of_kind(iat)
1941 IF (.NOT. any(xas_tdp_env%ex_atom_indices == iatom)) cycle
1942 tmp_index =
locate(xas_tdp_env%ex_atom_indices, iatom)
1945 DO istate = 1,
SIZE(xas_tdp_env%state_types, 1)
1947 IF (xas_tdp_env%state_types(istate, tmp_index) ==
xas_not_excited) cycle
1949 current_state => xas_tdp_env%donor_states(current_state_index)
1951 at_symbol=kind_name, kind_index=ikind, &
1952 state_type=xas_tdp_env%state_types(istate, tmp_index))
1954 IF (output_unit > 0)
THEN
1955 WRITE (output_unit,
"(/,T4,A,A2,A,I4,A,A,A)") &
1956 "-Donor state of type ", xas_tdp_env%state_type_char(current_state%state_type), &
1957 " for atom", current_state%at_index,
" of kind ", trim(current_state%at_symbol),
":"
1961 CALL assign_mos_to_donor_state(current_state, xas_tdp_env, xas_tdp_control, qs_env)
1962 CALL perform_mulliken_on_donor_state(current_state, qs_env)
1964 current_state_index = current_state_index + 1
1965 NULLIFY (current_state)
1971 IF (output_unit > 0)
THEN
1972 WRITE (output_unit,
"(/,T5,A)") &
1973 "Use LOCALIZE and/or increase N_SEARCH for better results, if so required."
1976 END SUBROUTINE print_checks
1986 SUBROUTINE compute_lenrep_multipole(iatom, xas_tdp_env, xas_tdp_control, qs_env)
1988 INTEGER,
INTENT(IN) :: iatom
1994 REAL(
dp),
DIMENSION(3) :: rc
1998 NULLIFY (work, particle_set)
2000 CALL get_qs_env(qs_env, particle_set=particle_set)
2001 rc = particle_set(iatom)%r
2004 IF (xas_tdp_control%dipole_form ==
xas_dip_len)
THEN
2006 CALL dbcsr_set(xas_tdp_env%dipmat(i)%matrix, 0.0_dp)
2007 work(i)%matrix => xas_tdp_env%dipmat(i)%matrix
2011 IF (xas_tdp_control%do_quad)
THEN
2013 CALL dbcsr_set(xas_tdp_env%quadmat(i)%matrix, 0.0_dp)
2014 work(3 + i)%matrix => xas_tdp_env%quadmat(i)%matrix
2017 IF (xas_tdp_control%dipole_form ==
xas_dip_vel) order = -2
2021 CALL rrc_xyz_ao(work, qs_env, rc, order=order, minimum_image=.true.)
2024 END SUBROUTINE compute_lenrep_multipole
2038 SUBROUTINE compute_dipole_fosc(donor_state, xas_tdp_control, xas_tdp_env)
2044 CHARACTER(len=*),
PARAMETER :: routinen =
'compute_dipole_fosc'
2046 INTEGER :: handle, iosc, j, nao, ndo_mo, ndo_so, &
2048 LOGICAL :: do_sc, do_sg
2049 REAL(
dp) :: osc_xyz, pref
2050 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: tot_contr
2051 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: dip_block
2052 REAL(
dp),
DIMENSION(:),
POINTER :: lr_evals
2053 REAL(
dp),
DIMENSION(:, :),
POINTER :: osc_str
2061 NULLIFY (dipmat, col_struct, mat_struct, para_env, blacs_env, lr_coeffs)
2062 NULLIFY (lr_evals, osc_str)
2064 CALL timeset(routinen, handle)
2067 do_sc = xas_tdp_control%do_spin_cons
2068 do_sg = xas_tdp_control%do_singlet
2071 lr_evals => donor_state%sc_evals
2072 lr_coeffs => donor_state%sc_coeffs
2073 ELSE IF (do_sg)
THEN
2075 lr_evals => donor_state%sg_evals
2076 lr_coeffs => donor_state%sg_coeffs
2078 cpabort(
"Dipole oscilaltor strength only for singlets and spin-conserving excitations.")
2080 ndo_mo = donor_state%ndo_mo
2081 ndo_so = ndo_mo*nspins
2082 ngs = ndo_so;
IF (xas_tdp_control%do_roks) ngs = ndo_mo
2083 nosc =
SIZE(lr_evals)
2084 ALLOCATE (donor_state%osc_str(nosc, 4))
2085 osc_str => donor_state%osc_str
2087 dipmat => xas_tdp_env%dipmat
2090 CALL cp_fm_get_info(donor_state%gs_coeffs, matrix_struct=col_struct, para_env=para_env, &
2091 context=blacs_env, nrow_global=nao)
2093 nrow_global=ndo_so*nosc, ncol_global=ngs)
2097 ALLOCATE (tot_contr(ndo_mo), dip_block(ndo_so, ngs))
2098 pref = 2.0_dp;
IF (do_sc) pref = 1.0_dp
2106 CALL parallel_gemm(
'T',
'N', ndo_so*nosc, ngs, nao, 1.0_dp, lr_coeffs, col_work, 0.0_dp, mat_work)
2112 CALL cp_fm_get_submatrix(fm=mat_work, target_m=dip_block, start_row=(iosc - 1)*ndo_so + 1, &
2113 start_col=1, n_rows=ndo_so, n_cols=ngs)
2116 ELSE IF (do_sc .AND. xas_tdp_control%do_uks)
THEN
2117 tot_contr(:) =
get_diag(dip_block(1:ndo_mo, 1:ndo_mo))
2118 tot_contr(:) = tot_contr(:) +
get_diag(dip_block(ndo_mo + 1:ndo_so, ndo_mo + 1:ndo_so))
2121 tot_contr(:) =
get_diag(dip_block(1:ndo_mo, :))
2122 tot_contr(:) = tot_contr(:) +
get_diag(dip_block(ndo_mo + 1:ndo_so, :))
2125 osc_xyz = sum(tot_contr)**2
2126 osc_str(iosc, 4) = osc_str(iosc, 4) + osc_xyz
2127 osc_str(iosc, j) = osc_xyz
2134 IF (xas_tdp_control%dipole_form ==
xas_dip_len)
THEN
2135 osc_str(:, j) = pref*2.0_dp/3.0_dp*lr_evals(:)*osc_str(:, j)
2137 osc_str(:, j) = pref*2.0_dp/3.0_dp/lr_evals(:)*osc_str(:, j)
2146 CALL timestop(handle)
2148 END SUBROUTINE compute_dipole_fosc
2158 SUBROUTINE compute_quadrupole_fosc(donor_state, xas_tdp_control, xas_tdp_env)
2164 CHARACTER(len=*),
PARAMETER :: routinen =
'compute_quadrupole_fosc'
2166 INTEGER :: handle, iosc, j, nao, ndo_mo, ndo_so, &
2168 LOGICAL :: do_sc, do_sg
2170 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: tot_contr, trace
2171 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: quad_block
2172 REAL(
dp),
DIMENSION(:),
POINTER :: lr_evals, osc_str
2180 NULLIFY (lr_evals, osc_str, lr_coeffs, col_struct, mat_struct, para_env)
2183 CALL timeset(routinen, handle)
2186 do_sc = xas_tdp_control%do_spin_cons
2187 do_sg = xas_tdp_control%do_singlet
2190 lr_evals => donor_state%sc_evals
2191 lr_coeffs => donor_state%sc_coeffs
2192 ELSE IF (do_sg)
THEN
2194 lr_evals => donor_state%sg_evals
2195 lr_coeffs => donor_state%sg_coeffs
2197 cpabort(
"Quadrupole oscillator strengths only for singlet and spin-conserving excitations")
2199 ndo_mo = donor_state%ndo_mo
2200 ndo_so = ndo_mo*nspins
2201 ngs = ndo_so;
IF (xas_tdp_control%do_roks) ngs = ndo_mo
2202 nosc =
SIZE(lr_evals)
2203 ALLOCATE (donor_state%quad_osc_str(nosc))
2204 osc_str => donor_state%quad_osc_str
2206 quadmat => xas_tdp_env%quadmat
2209 CALL cp_fm_get_info(donor_state%gs_coeffs, matrix_struct=col_struct, para_env=para_env, &
2210 context=blacs_env, nrow_global=nao)
2212 nrow_global=ndo_so*nosc, ncol_global=ngs)
2216 ALLOCATE (quad_block(ndo_so, ngs), tot_contr(ndo_mo))
2217 pref = 2.0_dp;
IF (do_sc) pref = 1.0_dp
2218 ALLOCATE (trace(nosc))
2227 CALL parallel_gemm(
'T',
'N', ndo_so*nosc, ngs, nao, 1.0_dp, lr_coeffs, col_work, 0.0_dp, mat_work)
2233 CALL cp_fm_get_submatrix(fm=mat_work, target_m=quad_block, start_row=(iosc - 1)*ndo_so + 1, &
2234 start_col=1, n_rows=ndo_so, n_cols=ngs)
2237 tot_contr(:) =
get_diag(quad_block)
2238 ELSE IF (do_sc .AND. xas_tdp_control%do_uks)
THEN
2239 tot_contr(:) =
get_diag(quad_block(1:ndo_mo, 1:ndo_mo))
2240 tot_contr(:) = tot_contr(:) +
get_diag(quad_block(ndo_mo + 1:ndo_so, ndo_mo + 1:ndo_so))
2243 tot_contr(:) =
get_diag(quad_block(1:ndo_mo, :))
2244 tot_contr(:) = tot_contr(:) +
get_diag(quad_block(ndo_mo + 1:ndo_so, :))
2248 IF (j == 1 .OR. j == 4 .OR. j == 6)
THEN
2249 osc_str(iosc) = osc_str(iosc) + sum(tot_contr)**2
2250 trace(iosc) = trace(iosc) + sum(tot_contr)
2254 osc_str(iosc) = osc_str(iosc) + 2.0_dp*sum(tot_contr)**2
2261 osc_str(:) = pref*1._dp/20._dp*
a_fine**2*lr_evals(:)**3*(osc_str(:) - 1._dp/3._dp*trace(:)**2)
2268 CALL timestop(handle)
2270 END SUBROUTINE compute_quadrupole_fosc
2279 SUBROUTINE write_mos_to_ex_atoms_association(xas_tdp_env, xas_tdp_control, qs_env)
2285 CHARACTER(LEN=default_string_length) :: kind_name
2286 INTEGER :: at_index, imo, ispin, nmo, nspins, &
2287 output_unit, tmp_index
2288 INTEGER,
DIMENSION(3) :: perd_init
2289 INTEGER,
DIMENSION(:),
POINTER :: ex_atom_indices
2290 INTEGER,
DIMENSION(:, :, :),
POINTER :: mos_of_ex_atoms
2291 REAL(
dp) :: dist, mo_spread
2292 REAL(
dp),
DIMENSION(3) :: at_pos, r_ac, wfn_center
2296 NULLIFY (cell, particle_set, mos_of_ex_atoms, ex_atom_indices)
2300 IF (output_unit > 0)
THEN
2301 WRITE (unit=output_unit, fmt=
"(/,T3,A,/,T3,A,/,T3,A)") &
2302 " Associated Associated Distance to MO spread (Ang^2)", &
2303 "Spin MO index atom index atom kind MO center (Ang) -w_i ln(|z_ij|^2)", &
2304 "---------------------------------------------------------------------------------"
2308 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
2309 mos_of_ex_atoms => xas_tdp_env%mos_of_ex_atoms
2310 ex_atom_indices => xas_tdp_env%ex_atom_indices
2311 nmo = xas_tdp_control%n_search
2312 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, cell=cell)
2315 perd_init = cell%perd
2320 DO ispin = 1, nspins
2323 IF (any(mos_of_ex_atoms(imo, :, ispin) == 1))
THEN
2324 tmp_index = maxloc(mos_of_ex_atoms(imo, :, ispin), 1)
2325 at_index = ex_atom_indices(tmp_index)
2326 kind_name = particle_set(at_index)%atomic_kind%name
2328 at_pos = particle_set(at_index)%r
2329 wfn_center = xas_tdp_env%qs_loc_env%localized_wfn_control%centers_set(ispin)%array(1:3, imo)
2330 r_ac =
pbc(at_pos, wfn_center, cell)
2335 mo_spread = xas_tdp_env%qs_loc_env%localized_wfn_control%centers_set(ispin)%array(4, imo)
2338 IF (output_unit > 0)
THEN
2339 WRITE (unit=output_unit, fmt=
"(T3,I4,I10,I14,A14,ES19.3,ES20.3)") &
2340 ispin, imo, at_index, trim(kind_name), dist, mo_spread
2347 IF (output_unit > 0)
THEN
2348 WRITE (unit=output_unit, fmt=
"(T3,A,/)") &
2349 "---------------------------------------------------------------------------------"
2353 cell%perd = perd_init
2355 END SUBROUTINE write_mos_to_ex_atoms_association
2366 SUBROUTINE perform_mulliken_on_donor_state(donor_state, qs_env)
2370 INTEGER :: at_index, i, ispin, nao, natom, ndo_mo, &
2371 ndo_so, nsgf, nspins, output_unit
2372 INTEGER,
DIMENSION(:),
POINTER :: first_sgf, last_sgf
2373 INTEGER,
DIMENSION(:, :),
POINTER :: mo_indices
2374 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: mul_pop, pop_mat
2375 REAL(
dp),
DIMENSION(:, :),
POINTER :: work_array
2383 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2385 NULLIFY (mo_indices, qs_kind_set, particle_set, first_sgf, work_array)
2386 NULLIFY (matrix_s, para_env, blacs_env, col_vect_struct, last_sgf)
2389 at_index = donor_state%at_index
2390 mo_indices => donor_state%mo_indices
2391 ndo_mo = donor_state%ndo_mo
2392 gs_coeffs => donor_state%gs_coeffs
2394 nspins = 1;
IF (
SIZE(mo_indices, 2) == 2) nspins = 2
2395 ndo_so = ndo_mo*nspins
2396 ALLOCATE (mul_pop(ndo_mo, nspins))
2399 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, qs_kind_set=qs_kind_set, &
2400 para_env=para_env, blacs_env=blacs_env, matrix_s=matrix_s)
2401 CALL cp_fm_get_info(gs_coeffs, nrow_global=nao, matrix_struct=col_vect_struct)
2403 natom =
SIZE(particle_set, 1)
2404 ALLOCATE (first_sgf(natom))
2405 ALLOCATE (last_sgf(natom))
2407 CALL get_particle_set(particle_set, qs_kind_set, first_sgf=first_sgf, last_sgf=last_sgf)
2408 nsgf = last_sgf(at_index) - first_sgf(at_index) + 1
2416 ALLOCATE (work_array(nsgf, ndo_so))
2417 ALLOCATE (pop_mat(ndo_so, ndo_so))
2419 CALL cp_fm_get_submatrix(fm=work_vect, target_m=work_array, start_row=first_sgf(at_index), &
2420 start_col=1, n_rows=nsgf, n_cols=ndo_so, transpose=.false.)
2422 CALL dgemm(
'T',
'N', ndo_so, ndo_so, nsgf, 1.0_dp, donor_state%contract_coeffs, nsgf, &
2423 work_array, nsgf, 0.0_dp, pop_mat, ndo_so)
2426 DO ispin = 1, nspins
2428 mul_pop(i, ispin) = pop_mat((ispin - 1)*ndo_mo + i, (ispin - 1)*ndo_mo + i)
2433 IF (output_unit > 0)
THEN
2434 WRITE (unit=output_unit, fmt=
"(T5,A,/,T5,A)") &
2435 "Mulliken population analysis retricted to the associated MO(s) yields: ", &
2436 " Spin MO index charge"
2437 DO ispin = 1, nspins
2439 WRITE (unit=output_unit, fmt=
"(T51,I4,I10,F11.3)") &
2440 ispin, mo_indices(i, ispin), mul_pop(i, ispin)
2446 DEALLOCATE (first_sgf, last_sgf, work_array)
2449 END SUBROUTINE perform_mulliken_on_donor_state
2459 SUBROUTINE xas_tdp_post(ex_type, donor_state, xas_tdp_env, xas_tdp_section, qs_env)
2461 INTEGER,
INTENT(IN) :: ex_type
2467 CHARACTER(len=*),
PARAMETER :: routinen =
'xas_tdp_post'
2469 CHARACTER(len=default_string_length) :: domo, domon, excite, pos, xas_mittle
2470 INTEGER :: ex_state_idx, handle, ic, ido_mo, imo, irep, ispin, n_dependent, n_rep, nao, &
2471 ncubes, ndo_mo, ndo_so, nlumo, nmo, nspins, output_unit
2472 INTEGER,
DIMENSION(:),
POINTER :: bounds,
list, state_list
2473 LOGICAL :: append_cube, do_cubes, do_pdos, &
2475 REAL(
dp),
DIMENSION(:),
POINTER :: lr_evals
2476 REAL(
dp),
DIMENSION(:, :),
POINTER :: centers
2488 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2491 NULLIFY (atomic_kind_set, particle_set, qs_kind_set, mo_set, lr_evals, lr_coeffs)
2492 NULLIFY (mo_struct, para_env, blacs_env, fm_struct, matrix_s, print_key, logger)
2493 NULLIFY (bounds, state_list,
list, mos)
2497 do_pdos = .false.; do_cubes = .false.; do_wfn_restart = .false.
2500 "PRINT%PDOS"),
cp_p_file)) do_pdos = .true.
2503 "PRINT%CUBES"),
cp_p_file)) do_cubes = .true.
2506 "PRINT%RESTART_WFN"),
cp_p_file)) do_wfn_restart = .true.
2508 IF (.NOT. (do_pdos .OR. do_cubes .OR. do_wfn_restart))
RETURN
2510 CALL timeset(routinen, handle)
2513 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, particle_set=particle_set, &
2514 qs_kind_set=qs_kind_set, para_env=para_env, blacs_env=blacs_env, &
2515 matrix_s=matrix_s, mos=mos)
2517 SELECT CASE (ex_type)
2519 lr_evals => donor_state%sc_evals
2520 lr_coeffs => donor_state%sc_coeffs
2524 lr_evals => donor_state%sf_evals
2525 lr_coeffs => donor_state%sf_coeffs
2529 lr_evals => donor_state%sg_evals
2530 lr_coeffs => donor_state%sg_coeffs
2534 lr_evals => donor_state%tp_evals
2535 lr_coeffs => donor_state%tp_coeffs
2540 SELECT CASE (donor_state%state_type)
2549 ndo_mo = donor_state%ndo_mo
2550 ndo_so = ndo_mo*nspins
2551 nmo =
SIZE(lr_evals)
2555 nrow_global=nao, ncol_global=nmo)
2559 IF (do_wfn_restart)
THEN
2562 IF (.NOT. (nspins == 1 .AND. donor_state%state_type ==
xas_1s_type))
THEN
2563 cpabort(
"RESTART.wfn file only available for RKS K-edge XAS spectroscopy")
2566 CALL section_vals_val_get(xas_tdp_section,
"PRINT%RESTART_WFN%EXCITED_STATE_INDEX", n_rep_val=n_rep)
2570 i_rep_val=irep, i_val=ex_state_idx)
2571 cpassert(ex_state_idx <=
SIZE(lr_evals))
2576 IF (
SIZE(mos) == 1) &
2577 restart_mos(ispin)%occupation_numbers = mos(1)%occupation_numbers/2
2580 CALL cp_fm_to_fm_submat(msource=lr_coeffs, mtarget=restart_mos(1)%mo_coeff, nrow=nao, &
2581 ncol=1, s_firstrow=1, s_firstcol=ex_state_idx, t_firstrow=1, &
2582 t_firstcol=donor_state%mo_indices(1, 1))
2584 xas_mittle =
'xasat'//trim(adjustl(
cp_to_string(donor_state%at_index)))//
'_'//trim(domo)// &
2585 '_'//trim(excite)//
'_idx'//trim(adjustl(
cp_to_string(ex_state_idx)))
2587 extension=
".wfn", file_status=
"REPLACE", &
2588 file_action=
"WRITE", file_form=
"UNFORMATTED", &
2589 middle_name=xas_mittle)
2592 qs_kind_set=qs_kind_set, ires=output_unit)
2607 IF (.NOT.
ASSOCIATED(xas_tdp_env%matrix_shalf) .AND. do_pdos)
THEN
2609 nrow_global=nao, ncol_global=nao)
2610 ALLOCATE (xas_tdp_env%matrix_shalf)
2615 CALL cp_fm_power(xas_tdp_env%matrix_shalf, work_fm, 0.5_dp, epsilon(0.0_dp), n_dependent)
2623 IF (output_unit > 0)
THEN
2624 WRITE (unit=output_unit, fmt=
"(/,T5,A,/,T5,A,/,T5,A)") &
2625 "Computing the PDOS of linear-response orbitals for spectral features analysis", &
2626 "Note: using standard PDOS routines => ignore mentions of KS states and MO ", &
2627 " occupation numbers. Eigenvalues in *.pdos files are excitations energies."
2632 IF (nlumo .NE. 0)
THEN
2633 cpwarn(
"NLUMO is irrelevant for XAS_TDP PDOS. It was overwritten to 0.")
2644 ncubes = bounds(2) - bounds(1) + 1
2645 IF (ncubes > 0)
THEN
2646 ALLOCATE (state_list(ncubes))
2648 state_list(ic) = bounds(1) + ic - 1
2652 IF (.NOT.
ASSOCIATED(state_list))
THEN
2659 IF (
ASSOCIATED(
list))
THEN
2661 DO ic = 1,
SIZE(
list)
2662 state_list(ncubes + ic) =
list(ic)
2664 ncubes = ncubes +
SIZE(
list)
2669 IF (.NOT.
ASSOCIATED(state_list))
THEN
2671 ALLOCATE (state_list(1))
2677 IF (append_cube) pos =
"APPEND"
2679 ALLOCATE (centers(6, ncubes))
2685 DO ido_mo = 1, ndo_mo
2686 DO ispin = 1, nspins
2690 CALL allocate_mo_set(mo_set, nao=nao, nmo=nmo, nelectron=nmo, n_el_f=real(nmo,
dp), &
2691 maxocc=1.0_dp, flexible_electron_count=0.0_dp)
2692 CALL init_mo_set(mo_set, fm_ref=mo_coeff, name=
"PDOS XAS_TDP MOs")
2693 mo_set%eigenvalues(:) = lr_evals(:)
2696 IF (nspins == 1 .AND. ndo_mo == 1)
THEN
2701 nrow=nao, ncol=1, s_firstrow=1, &
2702 s_firstcol=(imo - 1)*ndo_so + (ispin - 1)*ndo_mo + ido_mo, &
2703 t_firstrow=1, t_firstcol=imo)
2710 xas_mittle =
'xasat'//trim(adjustl(
cp_to_string(donor_state%at_index)))//
'_'// &
2711 trim(domon)//
'_'//trim(excite)
2715 qs_env, xas_tdp_section, ispin, xas_mittle, &
2716 external_matrix_shalf=xas_tdp_env%matrix_shalf)
2720 CALL qs_print_cubes(qs_env, mo_set%mo_coeff, ncubes, state_list, centers, &
2721 print_key=print_key, root=xas_mittle, ispin=ispin, &
2735 IF (do_cubes)
DEALLOCATE (centers, state_list)
2737 CALL timestop(handle)
2739 END SUBROUTINE xas_tdp_post
2749 SUBROUTINE make_lumo_guess(xas_tdp_env, xas_tdp_control, qs_env)
2751 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2752 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2753 TYPE(qs_environment_type),
POINTER :: qs_env
2755 CHARACTER(len=*),
PARAMETER :: routinen =
'make_lumo_guess'
2757 INTEGER :: handle, ispin, nao, nelec_spin(2), &
2758 nlumo(2), nocc(2), nspins
2760 REAL(dp),
ALLOCATABLE,
DIMENSION(:) :: evals
2761 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
2762 TYPE(cp_fm_struct_type),
POINTER :: fm_struct, lumo_struct
2763 TYPE(cp_fm_type) :: amatrix, bmatrix, evecs, work_fm
2764 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_ks, matrix_s
2765 TYPE(mp_para_env_type),
POINTER :: para_env
2767 NULLIFY (matrix_ks, matrix_s, para_env, blacs_env)
2768 NULLIFY (lumo_struct, fm_struct)
2770 CALL timeset(routinen, handle)
2772 do_os = xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks
2773 nspins = 1;
IF (do_os) nspins = 2
2774 ALLOCATE (xas_tdp_env%lumo_evecs(nspins))
2775 ALLOCATE (xas_tdp_env%lumo_evals(nspins))
2776 CALL get_qs_env(qs_env, matrix_ks=matrix_ks, matrix_s=matrix_s, nelectron_spin=nelec_spin, &
2777 para_env=para_env, blacs_env=blacs_env)
2778 CALL dbcsr_get_info(matrix_s(1)%matrix, nfullrows_total=nao)
2781 nlumo = nao - nelec_spin
2784 nlumo = nao - nelec_spin(1)/2
2785 nocc = nelec_spin(1)/2
2788 ALLOCATE (xas_tdp_env%ot_prec(nspins))
2790 DO ispin = 1, nspins
2793 CALL cp_fm_struct_create(fm_struct, para_env=para_env, context=blacs_env, &
2794 nrow_global=nao, ncol_global=nao)
2795 CALL cp_fm_create(amatrix, fm_struct)
2796 CALL cp_fm_create(bmatrix, fm_struct)
2797 CALL cp_fm_create(evecs, fm_struct)
2798 CALL cp_fm_create(work_fm, fm_struct)
2799 ALLOCATE (evals(nao))
2800 ALLOCATE (xas_tdp_env%lumo_evals(ispin)%array(nlumo(ispin)))
2802 CALL copy_dbcsr_to_fm(matrix_ks(ispin)%matrix, amatrix)
2803 CALL copy_dbcsr_to_fm(matrix_s(1)%matrix, bmatrix)
2806 CALL cp_fm_geeig(amatrix, bmatrix, evecs, evals, work_fm)
2809 CALL cp_fm_struct_create(lumo_struct, para_env=para_env, context=blacs_env, &
2810 nrow_global=nao, ncol_global=nlumo(ispin))
2811 CALL cp_fm_create(xas_tdp_env%lumo_evecs(ispin), lumo_struct)
2813 CALL cp_fm_to_fm_submat(evecs, xas_tdp_env%lumo_evecs(ispin), nrow=nao, &
2814 ncol=nlumo(ispin), s_firstrow=1, s_firstcol=nocc(ispin) + 1, &
2815 t_firstrow=1, t_firstcol=1)
2817 xas_tdp_env%lumo_evals(ispin)%array(1:nlumo(ispin)) = evals(nocc(ispin) + 1:nao)
2819 CALL build_ot_spin_prec(evecs, evals, ispin, xas_tdp_env, xas_tdp_control, qs_env)
2822 CALL cp_fm_release(amatrix)
2823 CALL cp_fm_release(bmatrix)
2824 CALL cp_fm_release(evecs)
2825 CALL cp_fm_release(work_fm)
2826 CALL cp_fm_struct_release(fm_struct)
2827 CALL cp_fm_struct_release(lumo_struct)
2831 CALL timestop(handle)
2833 END SUBROUTINE make_lumo_guess
2846 SUBROUTINE build_ot_spin_prec(evecs, evals, ispin, xas_tdp_env, xas_tdp_control, qs_env)
2848 TYPE(cp_fm_type),
INTENT(IN) :: evecs
2849 REAL(dp),
DIMENSION(:) :: evals
2851 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2852 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2853 TYPE(qs_environment_type),
POINTER :: qs_env
2855 CHARACTER(len=*),
PARAMETER :: routinen =
'build_ot_spin_prec'
2857 INTEGER :: handle, nao, nelec_spin(2), nguess, &
2861 REAL(dp),
ALLOCATABLE,
DIMENSION(:) :: scaling
2862 TYPE(cp_fm_struct_type),
POINTER :: fm_struct
2863 TYPE(cp_fm_type) :: fm_prec, work_fm
2864 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_s
2865 TYPE(mp_para_env_type),
POINTER :: para_env
2867 NULLIFY (fm_struct, para_env, matrix_s)
2869 CALL timeset(routinen, handle)
2871 do_os = xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks
2872 CALL get_qs_env(qs_env, para_env=para_env, nelectron_spin=nelec_spin, matrix_s=matrix_s)
2873 CALL cp_fm_get_info(evecs, nrow_global=nao, matrix_struct=fm_struct)
2874 CALL cp_fm_create(fm_prec, fm_struct)
2875 ALLOCATE (scaling(nao))
2876 nocc = nelec_spin(1)/2
2879 nocc = nelec_spin(ispin)
2885 IF (xas_tdp_control%n_excited > 0 .AND. xas_tdp_control%n_excited < nguess)
THEN
2886 nguess = xas_tdp_control%n_excited/nspins
2887 ELSE IF (xas_tdp_control%e_range > 0.0_dp)
THEN
2888 nguess = count(evals(nocc + 1:nao) - evals(nocc + 1) .LE. xas_tdp_control%e_range)
2892 scaling(nocc + 1:nocc + nguess) = 100.0_dp
2894 shift = evals(nocc + 1) - 0.01_dp
2895 scaling(nocc + nguess:nao) = 1.0_dp/(evals(nocc + nguess:nao) - shift)
2897 scaling(1:nocc) = 1.0_dp
2900 CALL cp_fm_create(work_fm, fm_struct)
2902 CALL cp_fm_copy_general(evecs, work_fm, para_env)
2903 CALL cp_fm_column_scale(work_fm, scaling)
2905 CALL parallel_gemm(
'N',
'T', nao, nao, nao, 1.0_dp, work_fm, evecs, 0.0_dp, fm_prec)
2908 ALLOCATE (xas_tdp_env%ot_prec(ispin)%matrix)
2909 CALL dbcsr_create(xas_tdp_env%ot_prec(ispin)%matrix, template=matrix_s(1)%matrix, name=
"OT_PREC")
2910 CALL copy_fm_to_dbcsr(fm_prec, xas_tdp_env%ot_prec(ispin)%matrix)
2911 CALL dbcsr_filter(xas_tdp_env%ot_prec(ispin)%matrix, xas_tdp_control%eps_filter)
2913 CALL cp_fm_release(work_fm)
2914 CALL cp_fm_release(fm_prec)
2916 CALL timestop(handle)
2918 END SUBROUTINE build_ot_spin_prec
2927 SUBROUTINE print_xps(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
2929 TYPE(donor_state_type),
POINTER :: donor_state
2930 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2931 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2932 TYPE(qs_environment_type),
POINTER :: qs_env
2934 INTEGER :: ido_mo, ispin, nspins, output_unit
2935 REAL(dp),
ALLOCATABLE,
DIMENSION(:, :) :: ips, soc_shifts
2937 output_unit = cp_logger_get_default_io_unit()
2939 nspins = 1;
IF (xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks) nspins = 2
2941 ALLOCATE (ips(
SIZE(donor_state%gw2x_evals, 1),
SIZE(donor_state%gw2x_evals, 2)))
2942 ips(:, :) = donor_state%gw2x_evals(:, :)
2945 IF (.NOT. xas_tdp_control%is_periodic)
THEN
2948 IF (donor_state%ndo_mo > 1)
THEN
2949 CALL get_soc_splitting(soc_shifts, donor_state, xas_tdp_env, xas_tdp_control, qs_env)
2950 ips(:, :) = ips(:, :) + soc_shifts
2952 IF (output_unit > 0)
THEN
2953 WRITE (output_unit, fmt=
"(/,T5,A,F23.6)") &
2954 "Ionization potentials for XPS (GW2X + SOC): ", -ips(1, 1)*evolt
2956 DO ispin = 1, nspins
2957 DO ido_mo = 1, donor_state%ndo_mo
2959 IF (ispin == 1 .AND. ido_mo == 1) cycle
2961 WRITE (output_unit, fmt=
"(T5,A,F23.6)") &
2962 " ", -ips(ido_mo, ispin)*evolt
2971 IF (output_unit > 0)
THEN
2972 WRITE (output_unit, fmt=
"(/,T5,A,F29.6)") &
2973 "Ionization potentials for XPS (GW2X): ", -ips(1, 1)*evolt
2975 IF (nspins == 2)
THEN
2976 WRITE (output_unit, fmt=
"(T5,A,F29.6)") &
2977 " ", -ips(1, 2)*evolt
2984 END SUBROUTINE print_xps
2993 SUBROUTINE print_xas_tdp_to_file(donor_state, xas_tdp_env, xas_tdp_control, xas_tdp_section)
2995 TYPE(donor_state_type),
POINTER :: donor_state
2996 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2997 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2998 TYPE(section_vals_type),
POINTER :: xas_tdp_section
3000 INTEGER :: i, output_unit, xas_tdp_unit
3001 TYPE(cp_logger_type),
POINTER :: logger
3004 logger => cp_get_default_logger()
3006 xas_tdp_unit = cp_print_key_unit_nr(logger, xas_tdp_section,
"PRINT%SPECTRUM", &
3007 extension=
".spectrum", file_position=
"APPEND", &
3008 file_action=
"WRITE", file_form=
"FORMATTED")
3010 output_unit = cp_logger_get_default_io_unit()
3012 IF (output_unit > 0)
THEN
3013 WRITE (output_unit, fmt=
"(/,T5,A,/)") &
3014 "Calculations done: "
3017 IF (xas_tdp_control%do_spin_cons)
THEN
3018 IF (xas_tdp_unit > 0)
THEN
3021 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3022 "==================================================================================", &
3023 "XAS TDP open-shell spin-conserving (no SOC) excitations for DONOR STATE: ", &
3024 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3025 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3026 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3027 "=================================================================================="
3031 IF (xas_tdp_control%do_quad)
THEN
3032 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3033 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3034 DO i = 1,
SIZE(donor_state%sc_evals)
3035 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3036 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4), &
3037 donor_state%quad_osc_str(i)
3039 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3040 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3041 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3042 DO i = 1,
SIZE(donor_state%sc_evals)
3043 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3044 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4), &
3045 donor_state%osc_str(i, 1), donor_state%osc_str(i, 2), donor_state%osc_str(i, 3)
3048 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3049 " Index Excitation energy (eV) fosc dipole (a.u.)"
3050 DO i = 1,
SIZE(donor_state%sc_evals)
3051 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3052 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4)
3056 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3059 IF (output_unit > 0)
THEN
3060 WRITE (output_unit, fmt=
"(T5,A,F17.6)") &
3061 "First spin-conserving XAS excitation energy (eV): ", donor_state%sc_evals(1)*evolt
3066 IF (xas_tdp_control%do_spin_flip)
THEN
3067 IF (xas_tdp_unit > 0)
THEN
3070 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3071 "==================================================================================", &
3072 "XAS TDP open-shell spin-flip (no SOC) excitations for DONOR STATE: ", &
3073 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3074 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3075 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3076 "=================================================================================="
3080 IF (xas_tdp_control%do_quad)
THEN
3081 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3082 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3083 DO i = 1,
SIZE(donor_state%sf_evals)
3084 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3085 i, donor_state%sf_evals(i)*evolt, 0.0_dp, 0.0_dp
3087 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3088 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3089 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3090 DO i = 1,
SIZE(donor_state%sf_evals)
3091 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3092 i, donor_state%sf_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp
3095 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3096 " Index Excitation energy (eV) fosc dipole (a.u.)"
3097 DO i = 1,
SIZE(donor_state%sf_evals)
3098 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3099 i, donor_state%sf_evals(i)*evolt, 0.0_dp
3103 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3106 IF (output_unit > 0)
THEN
3107 WRITE (output_unit, fmt=
"(T5,A,F23.6)") &
3108 "First spin-flip XAS excitation energy (eV): ", donor_state%sf_evals(1)*evolt
3112 IF (xas_tdp_control%do_singlet)
THEN
3113 IF (xas_tdp_unit > 0)
THEN
3116 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3117 "==================================================================================", &
3118 "XAS TDP singlet excitations (no SOC) for DONOR STATE: ", &
3119 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3120 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3121 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3122 "=================================================================================="
3126 IF (xas_tdp_control%do_quad)
THEN
3127 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3128 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3129 DO i = 1,
SIZE(donor_state%sg_evals)
3130 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3131 i, donor_state%sg_evals(i)*evolt, donor_state%osc_str(i, 4), &
3132 donor_state%quad_osc_str(i)
3134 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3135 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3136 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3137 DO i = 1,
SIZE(donor_state%sg_evals)
3138 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3139 i, donor_state%sg_evals(i)*evolt, donor_state%osc_str(i, 4), &
3140 donor_state%osc_str(i, 1), donor_state%osc_str(i, 2), donor_state%osc_str(i, 3)
3143 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3144 " Index Excitation energy (eV) fosc dipole (a.u.)"
3145 DO i = 1,
SIZE(donor_state%sg_evals)
3146 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3147 i, donor_state%sg_evals(i)*evolt, donor_state%osc_str(i, 4)
3151 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3154 IF (output_unit > 0)
THEN
3155 WRITE (output_unit, fmt=
"(T5,A,F25.6)") &
3156 "First singlet XAS excitation energy (eV): ", donor_state%sg_evals(1)*evolt
3160 IF (xas_tdp_control%do_triplet)
THEN
3161 IF (xas_tdp_unit > 0)
THEN
3164 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3165 "==================================================================================", &
3166 "XAS TDP triplet excitations (no SOC) for DONOR STATE: ", &
3167 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3168 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3169 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3170 "=================================================================================="
3174 IF (xas_tdp_control%do_quad)
THEN
3175 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3176 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3177 DO i = 1,
SIZE(donor_state%tp_evals)
3178 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3179 i, donor_state%tp_evals(i)*evolt, 0.0_dp, 0.0_dp
3181 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3182 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3183 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3184 DO i = 1,
SIZE(donor_state%tp_evals)
3185 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3186 i, donor_state%tp_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp
3189 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3190 " Index Excitation energy (eV) fosc dipole (a.u.)"
3191 DO i = 1,
SIZE(donor_state%tp_evals)
3192 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3193 i, donor_state%tp_evals(i)*evolt, 0.0_dp
3197 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3200 IF (output_unit > 0)
THEN
3201 WRITE (output_unit, fmt=
"(T5,A,F25.6)") &
3202 "First triplet XAS excitation energy (eV): ", donor_state%tp_evals(1)*evolt
3206 IF (xas_tdp_control%do_soc .AND. donor_state%state_type == xas_2p_type)
THEN
3207 IF (xas_tdp_unit > 0)
THEN
3210 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3211 "==================================================================================", &
3212 "XAS TDP excitations after spin-orbit coupling for DONOR STATE: ", &
3213 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3214 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3215 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3216 "=================================================================================="
3219 IF (xas_tdp_control%do_quad)
THEN
3220 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3221 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3222 DO i = 1,
SIZE(donor_state%soc_evals)
3223 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3224 i, donor_state%soc_evals(i)*evolt, donor_state%soc_osc_str(i, 4), &
3225 donor_state%soc_quad_osc_str(i)
3227 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3228 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3229 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3230 DO i = 1,
SIZE(donor_state%soc_evals)
3231 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3232 i, donor_state%soc_evals(i)*evolt, donor_state%soc_osc_str(i, 4), &
3233 donor_state%soc_osc_str(i, 1), donor_state%soc_osc_str(i, 2), donor_state%soc_osc_str(i, 3)
3236 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3237 " Index Excitation energy (eV) fosc dipole (a.u.)"
3238 DO i = 1,
SIZE(donor_state%soc_evals)
3239 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3240 i, donor_state%soc_evals(i)*evolt, donor_state%soc_osc_str(i, 4)
3244 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3247 IF (output_unit > 0)
THEN
3248 WRITE (output_unit, fmt=
"(T5,A,F29.6)") &
3249 "First SOC XAS excitation energy (eV): ", donor_state%soc_evals(1)*evolt
3253 CALL cp_print_key_finished_output(xas_tdp_unit, logger, xas_tdp_section,
"PRINT%SPECTRUM")
3255 END SUBROUTINE print_xas_tdp_to_file
3265 SUBROUTINE write_donor_state_restart(ex_type, donor_state, xas_tdp_section, qs_env)
3267 INTEGER,
INTENT(IN) :: ex_type
3268 TYPE(donor_state_type),
POINTER :: donor_state
3269 TYPE(section_vals_type),
POINTER :: xas_tdp_section
3270 TYPE(qs_environment_type),
POINTER :: qs_env
3272 CHARACTER(len=*),
PARAMETER :: routinen =
'write_donor_state_restart'
3274 CHARACTER(len=default_path_length) :: filename
3275 CHARACTER(len=default_string_length) :: domo, excite, my_middle
3276 INTEGER :: ex_atom, handle, ispin, nao, ndo_mo, &
3277 nex, nspins, output_unit, rst_unit, &
3279 INTEGER,
DIMENSION(:, :),
POINTER :: mo_indices
3281 REAL(dp),
DIMENSION(:),
POINTER :: lr_evals
3282 TYPE(cp_fm_type),
POINTER :: lr_coeffs
3283 TYPE(cp_logger_type),
POINTER :: logger
3284 TYPE(mo_set_type),
DIMENSION(:),
POINTER :: mos
3285 TYPE(section_vals_type),
POINTER :: print_key
3287 NULLIFY (logger, lr_coeffs, lr_evals, print_key, mos)
3290 logger => cp_get_default_logger()
3292 IF (btest(cp_print_key_should_output(logger%iter_info, xas_tdp_section, &
3293 "PRINT%RESTART", used_print_key=print_key), cp_p_file)) do_print = .true.
3295 IF (.NOT. do_print)
RETURN
3297 CALL timeset(routinen, handle)
3299 output_unit = cp_logger_get_default_io_unit()
3302 SELECT CASE (ex_type)
3303 CASE (tddfpt_spin_cons)
3304 lr_evals => donor_state%sc_evals
3305 lr_coeffs => donor_state%sc_coeffs
3308 CASE (tddfpt_spin_flip)
3309 lr_evals => donor_state%sf_evals
3310 lr_coeffs => donor_state%sf_coeffs
3313 CASE (tddfpt_singlet)
3314 lr_evals => donor_state%sg_evals
3315 lr_coeffs => donor_state%sg_coeffs
3318 CASE (tddfpt_triplet)
3319 lr_evals => donor_state%tp_evals
3320 lr_coeffs => donor_state%tp_coeffs
3325 SELECT CASE (donor_state%state_type)
3334 ndo_mo = donor_state%ndo_mo
3335 nex =
SIZE(lr_evals)
3336 CALL cp_fm_get_info(lr_coeffs, nrow_global=nao)
3337 state_type = donor_state%state_type
3338 ex_atom = donor_state%at_index
3339 mo_indices => donor_state%mo_indices
3343 my_middle =
'xasat'//trim(adjustl(cp_to_string(ex_atom)))//
'_'//trim(domo)//
'_'//trim(excite)
3344 rst_unit = cp_print_key_unit_nr(logger, xas_tdp_section,
"PRINT%RESTART", extension=
".rst", &
3345 file_status=
"REPLACE", file_action=
"WRITE", &
3346 file_form=
"UNFORMATTED", middle_name=trim(my_middle))
3348 filename = cp_print_key_generate_filename(logger, print_key, middle_name=trim(my_middle), &
3349 extension=
".rst", my_local=.false.)
3351 IF (output_unit > 0)
THEN
3352 WRITE (unit=output_unit, fmt=
"(/,T5,A,/T5,A,A,A)") &
3353 "Linear-response orbitals and excitation energies are written in: ", &
3354 '"', trim(filename),
'"'
3358 IF (rst_unit > 0)
THEN
3359 WRITE (rst_unit) ex_atom, state_type, ndo_mo, ex_type
3360 WRITE (rst_unit) nao, nex, nspins
3361 WRITE (rst_unit) mo_indices(:, :)
3362 WRITE (rst_unit) lr_evals(:)
3364 CALL cp_fm_write_unformatted(lr_coeffs, rst_unit)
3367 CALL get_qs_env(qs_env, mos=mos)
3368 DO ispin = 1, nspins
3369 CALL cp_fm_write_unformatted(mos(ispin)%mo_coeff, rst_unit)
3373 CALL cp_print_key_finished_output(rst_unit, logger, xas_tdp_section,
"PRINT%RESTART")
3375 CALL timestop(handle)
3377 END SUBROUTINE write_donor_state_restart
3386 SUBROUTINE read_donor_state_restart(donor_state, ex_type, filename, qs_env)
3388 TYPE(donor_state_type),
POINTER :: donor_state
3389 INTEGER,
INTENT(OUT) :: ex_type
3390 CHARACTER(len=*),
INTENT(IN) :: filename
3391 TYPE(qs_environment_type),
POINTER :: qs_env
3393 CHARACTER(len=*),
PARAMETER :: routinen =
'read_donor_state_restart'
3395 INTEGER :: handle, ispin, nao, nex, nspins, &
3396 output_unit, read_params(7), rst_unit
3397 INTEGER,
DIMENSION(:, :),
POINTER :: mo_indices
3398 LOGICAL :: file_exists
3399 REAL(dp),
DIMENSION(:),
POINTER :: lr_evals
3400 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
3401 TYPE(cp_fm_struct_type),
POINTER :: fm_struct
3402 TYPE(cp_fm_type),
POINTER :: lr_coeffs
3403 TYPE(mo_set_type),
DIMENSION(:),
POINTER :: mos
3404 TYPE(mp_comm_type) :: group
3405 TYPE(mp_para_env_type),
POINTER :: para_env
3407 NULLIFY (lr_evals, lr_coeffs, para_env, fm_struct, blacs_env, mos)
3409 CALL timeset(routinen, handle)
3411 output_unit = cp_logger_get_default_io_unit()
3412 cpassert(
ASSOCIATED(donor_state))
3413 CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
3416 file_exists = .false.
3419 IF (para_env%is_source())
THEN
3421 INQUIRE (file=filename, exist=file_exists)
3422 IF (.NOT. file_exists) cpabort(
"Trying to read non-existing XAS_TDP restart file")
3424 CALL open_file(file_name=trim(filename), file_action=
"READ", file_form=
"UNFORMATTED", &
3425 file_position=
"REWIND", file_status=
"OLD", unit_number=rst_unit)
3428 IF (output_unit > 0)
THEN
3429 WRITE (unit=output_unit, fmt=
"(/,T5,A,/,T5,A,A,A)") &
3430 "Reading linear-response orbitals and excitation energies from file: ", &
3435 IF (rst_unit > 0)
THEN
3436 READ (rst_unit) read_params(1:4)
3437 READ (rst_unit) read_params(5:7)
3439 CALL group%bcast(read_params)
3440 donor_state%at_index = read_params(1)
3441 donor_state%state_type = read_params(2)
3442 donor_state%ndo_mo = read_params(3)
3443 ex_type = read_params(4)
3444 nao = read_params(5)
3445 nex = read_params(6)
3446 nspins = read_params(7)
3448 ALLOCATE (mo_indices(donor_state%ndo_mo, nspins))
3449 IF (rst_unit > 0)
THEN
3450 READ (rst_unit) mo_indices(1:donor_state%ndo_mo, 1:nspins)
3452 CALL group%bcast(mo_indices)
3453 donor_state%mo_indices => mo_indices
3456 ALLOCATE (lr_evals(nex))
3457 IF (rst_unit > 0)
READ (rst_unit) lr_evals(1:nex)
3458 CALL group%bcast(lr_evals)
3461 CALL cp_fm_struct_create(fm_struct, context=blacs_env, para_env=para_env, &
3462 nrow_global=nao, ncol_global=nex*donor_state%ndo_mo*nspins)
3463 ALLOCATE (lr_coeffs)
3464 CALL cp_fm_create(lr_coeffs, fm_struct)
3465 CALL cp_fm_read_unformatted(lr_coeffs, rst_unit)
3466 CALL cp_fm_struct_release(fm_struct)
3469 CALL get_qs_env(qs_env, mos=mos)
3470 DO ispin = 1, nspins
3471 CALL cp_fm_read_unformatted(mos(ispin)%mo_coeff, rst_unit)
3475 IF (para_env%is_source())
THEN
3476 CALL close_file(unit_number=rst_unit)
3480 SELECT CASE (ex_type)
3481 CASE (tddfpt_spin_cons)
3482 donor_state%sc_evals => lr_evals
3483 donor_state%sc_coeffs => lr_coeffs
3484 CASE (tddfpt_spin_flip)
3485 donor_state%sf_evals => lr_evals
3486 donor_state%sf_coeffs => lr_coeffs
3487 CASE (tddfpt_singlet)
3488 donor_state%sg_evals => lr_evals
3489 donor_state%sg_coeffs => lr_coeffs
3490 CASE (tddfpt_triplet)
3491 donor_state%tp_evals => lr_evals
3492 donor_state%tp_coeffs => lr_coeffs
3495 CALL timestop(handle)
3497 END SUBROUTINE read_donor_state_restart
3505 SUBROUTINE restart_calculation(rst_filename, xas_tdp_section, qs_env)
3507 CHARACTER(len=*),
INTENT(IN) :: rst_filename
3508 TYPE(section_vals_type),
POINTER :: xas_tdp_section
3509 TYPE(qs_environment_type),
POINTER :: qs_env
3512 TYPE(donor_state_type),
POINTER :: donor_state
3513 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
3515 NULLIFY (xas_tdp_env, donor_state)
3518 ALLOCATE (donor_state)
3519 CALL donor_state_create(donor_state)
3520 CALL read_donor_state_restart(donor_state, ex_type, rst_filename, qs_env)
3523 CALL xas_tdp_env_create(xas_tdp_env)
3524 CALL xas_tdp_post(ex_type, donor_state, xas_tdp_env, xas_tdp_section, qs_env)
3527 CALL xas_tdp_env_release(xas_tdp_env)
3528 CALL free_ds_memory(donor_state)
3529 DEALLOCATE (donor_state%mo_indices)
3530 DEALLOCATE (donor_state)
3532 END SUBROUTINE restart_calculation
static void dgemm(const char transa, const char transb, const int m, const int n, const int k, const double alpha, const double *a, const int lda, const double *b, const int ldb, const double beta, double *c, const int ldc)
Convenient wrapper to hide Fortran nature of dgemm_, swapping a and b.
Types and set/get functions for auxiliary density matrix methods.
Contains methods used in the context of density fitting.
subroutine, public admm_uncorrect_for_eigenvalues(ispin, admm_env, ks_matrix)
...
subroutine, public admm_correct_for_eigenvalues(ispin, admm_env, ks_matrix)
...
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
subroutine, public get_gto_basis_set(gto_basis_set, name, aliases, norm_type, kind_radius, ncgf, nset, nsgf, cgf_symbol, sgf_symbol, norm_cgf, set_radius, lmax, lmin, lx, ly, lz, m, ncgf_set, npgf, nsgf_set, nshell, cphi, pgf_radius, sphi, scon, zet, first_cgf, first_sgf, l, last_cgf, last_sgf, n, gcc, maxco, maxl, maxpgf, maxsgf_set, maxshell, maxso, nco_sum, npgf_sum, nshell_sum, maxder, short_kind_radius, npgf_seg_sum)
...
subroutine, public deallocate_gto_basis_set(gto_basis_set)
...
pure real(dp) function, public srules(z, ne, n, l)
...
subroutine, public deallocate_sto_basis_set(sto_basis_set)
...
subroutine, public allocate_sto_basis_set(sto_basis_set)
...
subroutine, public create_gto_from_sto_basis(sto_basis_set, gto_basis_set, ngauss, ortho)
...
subroutine, public set_sto_basis_set(sto_basis_set, name, nshell, symbol, nq, lq, zet)
...
subroutine, public init_orb_basis_set(gto_basis_set)
Initialise a Gaussian-type orbital (GTO) basis set data set.
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public bussy2021a
Handles all functions related to the CELL.
methods related to the blacs parallel environment
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_multiply(transa, transb, alpha, matrix_a, matrix_b, beta, matrix_c, first_row, last_row, first_column, last_column, first_k, last_k, retain_sparsity, filter_eps, flop)
...
subroutine, public dbcsr_get_info(matrix, nblkrows_total, nblkcols_total, nfullrows_total, nfullcols_total, nblkrows_local, nblkcols_local, nfullrows_local, nfullcols_local, my_prow, my_pcol, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, row_blk_offset, col_blk_offset, distribution, name, matrix_type, group)
...
subroutine, public dbcsr_filter(matrix, eps)
...
real(kind=dp) function, public dbcsr_get_occupation(matrix)
...
subroutine, public dbcsr_finalize(matrix)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_complete_redistribute(matrix, redist)
...
subroutine, public dbcsr_add_on_diag(matrix, alpha)
Adds the given scalar to the diagonal of the matrix. Reserves any missing diagonal blocks.
DBCSR operations in CP2K.
subroutine, public cp_dbcsr_sm_fm_multiply(matrix, fm_in, fm_out, ncol, alpha, beta)
multiply a dbcsr with a fm matrix
subroutine, public copy_dbcsr_to_fm(matrix, fm)
Copy a DBCSR matrix to a BLACS matrix.
subroutine, public copy_fm_to_dbcsr(fm, matrix, keep_sparsity)
Copy a BLACS matrix to a dbcsr matrix.
Utility routines to open and close files. Tracking of preconnections.
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
basic linear algebra operations for full matrices
subroutine, public cp_fm_column_scale(matrixa, scaling)
scales column i of matrix a with scaling(i)
used for collecting some of the diagonalization schemes available for cp_fm_type. cp_fm_power also mo...
subroutine, public cp_fm_power(matrix, work, exponent, threshold, n_dependent, verbose, eigvals)
...
subroutine, public cp_fm_syevd(matrix, eigenvectors, eigenvalues, info)
Computes all eigenvalues and vectors of a real symmetric matrix significantly faster than syevx,...
subroutine, public cp_fm_geeig(amatrix, bmatrix, eigenvectors, eigenvalues, work)
General Eigenvalue Problem AX = BXE Single option version: Cholesky decomposition of B.
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
subroutine, public cp_fm_copy_general(source, destination, para_env)
General copy of a fm matrix to another fm matrix. Uses non-blocking MPI rather than ScaLAPACK.
subroutine, public cp_fm_get_diag(matrix, diag)
returns the diagonal elements of a fm
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_write_unformatted(fm, unit)
...
subroutine, public cp_fm_read_unformatted(fm, unit)
...
subroutine, public cp_fm_to_fm_submat(msource, mtarget, nrow, ncol, s_firstrow, s_firstcol, t_firstrow, t_firstcol)
copy just a part ot the matrix
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_get_submatrix(fm, target_m, start_row, start_col, n_rows, n_cols, transpose)
gets a submatrix of a full matrix op(target_m)(1:n_rows,1:n_cols) =fm(start_row:start_row+n_rows,...
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
various routines to log and control the output. The idea is that decisions about where to log should ...
integer function, public cp_logger_get_default_io_unit(logger)
returns the unit nr for the ionode (-1 on all other processors) skips as well checks if the procs cal...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer, parameter, public debug_print_level
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
character(len=default_path_length) function, public cp_print_key_generate_filename(logger, print_key, middle_name, extension, my_local)
Utility function that returns a unit number to write the print key. Might open a file with a unique f...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
integer, parameter, public cp_p_file
integer function, public cp_print_key_should_output(iteration_info, basis_section, print_key_path, used_print_key, first_time)
returns what should be done with the given property if btest(res,cp_p_store) then the property should...
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
integer, parameter, public default_path_length
Interface to the Libint-Library or a c++ wrapper.
subroutine, public cp_libint_static_init()
An array-based list which grows on demand. When the internal array is full, a new array of twice the ...
Machine interface based on Fortran 2003 and POSIX.
subroutine, public m_flush(lunit)
flushes units if the &GLOBAL flag is set accordingly
Collection of simple mathematical functions and subroutines.
pure real(kind=dp) function, dimension(min(size(a, 1), size(a, 2))), public get_diag(a)
Return the diagonal elements of matrix a as a vector.
subroutine, public diag(n, a, d, v)
Diagonalize matrix a. The eigenvalues are returned in vector d and the eigenvectors are returned in m...
Utility routines for the memory handling.
Interface to the message passing library MPI.
basic linear algebra operations for full matrixes
Parallel (pseudo)random number generator (RNG) for multiple streams and substreams of random numbers.
integer, parameter, public uniform
Define methods related to particle_type.
subroutine, public get_particle_set(particle_set, qs_kind_set, first_sgf, last_sgf, nsgf, nmao, basis)
Get the components of a particle set.
Define the data structure for the particle information.
Periodic Table related data definitions.
type(atom), dimension(0:nelem), public ptable
Definition of physical constants:
real(kind=dp), parameter, public a_fine
real(kind=dp), parameter, public evolt
real(kind=dp), parameter, public angstrom
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, ecoul_1c, rho0_s_rs, rho0_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs)
Get the QUICKSTEP environment.
Calculate the interaction radii for the operator matrix calculation.
subroutine, public init_interaction_radii_orb_basis(orb_basis_set, eps_pgf_orb, eps_pgf_short)
...
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, u_of_dft_plus_u, j_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, j0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, init_u_ramping_each_scf, reltmat, ghost, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
Driver for the localization that should be general for all the methods available and all the definiti...
subroutine, public qs_loc_driver(qs_env, qs_loc_env, print_loc_section, myspin, ext_mo_coeff)
set up the calculation of localized orbitals
Driver for the localization that should be general for all the methods available and all the definiti...
subroutine, public centers_spreads_berry(qs_loc_env, zij, nmoloc, cell, weights, ispin, print_loc_section, only_initial_out)
...
subroutine, public qs_print_cubes(qs_env, mo_coeff, nstates, state_list, centers, print_key, root, ispin, idir, state0, file_position)
write the cube files for a set of selected states
New version of the module for the localization of the molecular orbitals This should be able to use d...
subroutine, public localized_wfn_control_create(localized_wfn_control)
create the localized_wfn_control_type
subroutine, public qs_loc_env_release(qs_loc_env)
...
subroutine, public get_qs_loc_env(qs_loc_env, cell, local_molecules, localized_wfn_control, moloc_coeff, op_sm_set, op_fm_set, para_env, particle_set, weights, dim_op)
...
subroutine, public qs_loc_env_create(qs_loc_env)
...
Some utilities for the construction of the localization environment.
subroutine, public qs_loc_env_init(qs_loc_env, localized_wfn_control, qs_env, myspin, do_localize, loc_coeff, mo_loc_history)
allocates the data, and initializes the operators
subroutine, public set_loc_centers(localized_wfn_control, nmoloc, nspins)
create the center and spread array and the file names for the output
subroutine, public qs_loc_control_init(qs_loc_env, loc_section, do_homo, do_mixed, do_xas, nloc_xas, spin_xas)
initializes everything needed for localization of the HOMOs
Definition and initialisation of the mo data type.
subroutine, public write_mo_set_low(mo_array, qs_kind_set, particle_set, ires, rt_mos)
...
collects routines that perform operations directly related to MOs
Definition and initialisation of the mo data type.
subroutine, public duplicate_mo_set(mo_set_new, mo_set_old)
allocate a new mo_set, and copy the old data
subroutine, public allocate_mo_set(mo_set, nao, nmo, nelectron, n_el_f, maxocc, flexible_electron_count)
Allocates a mo set and partially initializes it (nao,nmo,nelectron, and flexible_electron_count are v...
subroutine, public deallocate_mo_set(mo_set)
Deallocate a wavefunction data structure.
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kts, mu, flexible_electron_count)
Get the components of a MO set data structure.
subroutine, public init_mo_set(mo_set, fm_pool, fm_ref, fm_struct, name)
initializes an allocated mo_set. eigenvalues, mo_coeff, occupation_numbers are valid only after this ...
subroutine, public p_xyz_ao(op, qs_env, minimum_image)
Calculation of the components of the dipole operator in the velocity form The elements of the sparse ...
subroutine, public rrc_xyz_ao(op, qs_env, rc, order, minimum_image, soft)
Calculation of the components of the dipole operator in the length form by taking the relative positi...
Calculation and writing of projected density of states The DOS is computed per angular momentum and p...
subroutine, public calculate_projected_dos(mo_set, atomic_kind_set, qs_kind_set, particle_set, qs_env, dft_section, ispin, xas_mittle, external_matrix_shalf)
Compute and write projected density of states.
superstucture that hold various representations of the density and keeps track of which ones are vali...
subroutine, public qs_rho_get(rho_struct, rho_ao, rho_ao_im, rho_ao_kp, rho_ao_im_kp, rho_r, drho_r, rho_g, drho_g, tau_r, tau_g, rho_r_valid, drho_r_valid, rho_g_valid, drho_g_valid, tau_r_valid, tau_g_valid, tot_rho_r, tot_rho_g, rho_r_sccs, soft_valid, complex_rho_ao)
returns info about the density described by this object. If some representation is not available an e...
module that contains the definitions of the scf types
integer, parameter, public ot_method_nr
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)
Overall control and environment types initialization.
subroutine, public xas_tdp(qs_env)
Driver for XAS TDDFT calculations.
Define XAS TDP control type and associated create, release, etc subroutines, as well as XAS TDP envir...
subroutine, public xas_tdp_env_create(xas_tdp_env)
Creates a TDP XAS environment type.
subroutine, public xas_tdp_env_release(xas_tdp_env)
Releases the TDP XAS environment type.
subroutine, public donor_state_create(donor_state)
Creates a donor_state.
subroutine, public xas_tdp_control_release(xas_tdp_control)
Releases the xas_tdp_control_type.
subroutine, public xas_atom_env_create(xas_atom_env)
Creates a xas_atom_env type.
subroutine, public set_xas_tdp_env(xas_tdp_env, nex_atoms, nex_kinds)
Sets values of selected variables within the TDP XAS environment type.
subroutine, public free_ds_memory(donor_state)
Deallocate a donor_state's heavy attributes.
subroutine, public set_donor_state(donor_state, at_index, at_symbol, kind_index, state_type)
sets specified values of the donor state type
subroutine, public xas_tdp_control_create(xas_tdp_control)
Creates and initializes the xas_tdp_control_type.
subroutine, public free_exat_memory(xas_tdp_env, atom, end_of_batch)
Releases the memory heavy attribute of xas_tdp_env that are specific to the current excited atom.
subroutine, public xas_atom_env_release(xas_atom_env)
Releases the xas_atom_env type.
subroutine, public read_xas_tdp_control(xas_tdp_control, xas_tdp_section)
Reads the inputs and stores in xas_tdp_control_type.
Utilities for X-ray absorption spectroscopy using TDDFPT.
subroutine, public include_rcs_soc(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
Includes the SOC effects on the precomputed restricted closed-shell singlet and triplet excitations....
subroutine, public setup_xas_tdp_prob(donor_state, qs_env, xas_tdp_env, xas_tdp_control)
Builds the matrix that defines the XAS TDDFPT generalized eigenvalue problem to be solved for excitat...
subroutine, public solve_xas_tdp_prob(donor_state, xas_tdp_control, xas_tdp_env, qs_env, ex_type)
Solves the XAS TDP generalized eigenvalue problem omega*C = matrix_tdp*C using standard full diagonal...
subroutine, public include_os_soc(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
Includes the SOC effects on the precomputed spin-conserving and spin-flip excitations from an open-sh...
Writes information on XC functionals to output.
subroutine, public xc_write(iounit, xc_section, lsd)
...
stores some data used in wavefunction fitting
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
keeps the information about the structure of a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.
A type that holds controlling information for the calculation of the spread of wfn and the optimizati...
contains all the info needed by quickstep to calculate the spread of a selected set of orbitals and i...
keeps the density in various representations, keeping track of which ones are valid.
Type containing informations about a single donor state.
a environment type that contains all the info needed for XAS_TDP atomic grid calculations
Type containing control information for TDP XAS calculations.
Type containing informations such as inputs and results for TDP XAS calculations.