55 USE dbcsr_api,
ONLY: &
56 dbcsr_add_on_diag, dbcsr_complete_redistribute, dbcsr_copy, dbcsr_create, dbcsr_filter, &
57 dbcsr_finalize, dbcsr_get_info, dbcsr_get_occupation, dbcsr_multiply, dbcsr_p_type, &
58 dbcsr_release, dbcsr_set, dbcsr_type, dbcsr_type_antisymmetric, dbcsr_type_no_symmetry, &
102 localized_wfn_control_type,&
146 #include "./base/base_uses.f90"
151 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'xas_tdp_methods'
165 TYPE(qs_environment_type),
POINTER :: qs_env
167 CHARACTER(len=*),
PARAMETER :: routinen =
'xas_tdp'
169 CHARACTER(default_string_length) :: rst_filename
170 INTEGER :: handle, n_rep, output_unit
171 LOGICAL :: do_restart
172 TYPE(section_vals_type),
POINTER :: xas_tdp_section
174 CALL timeset(routinen, handle)
177 NULLIFY (xas_tdp_section)
181 IF (output_unit > 0)
THEN
182 WRITE (unit=output_unit, fmt=
"(/,T3,A,/,T3,A,/,T3,A,/,T3,A,/)") &
183 "!===========================================================================!", &
185 "! Starting TDDFPT driven X-rays absorption spectroscopy calculations !", &
186 "!===========================================================================!"
204 IF (output_unit > 0)
THEN
205 WRITE (unit=output_unit, fmt=
"(/,T3,A)") &
206 "# This is a RESTART calculation for PDOS and/or CUBE printing"
209 CALL restart_calculation(rst_filename, xas_tdp_section, qs_env)
213 CALL xas_tdp_core(xas_tdp_section, qs_env)
216 IF (output_unit > 0)
THEN
217 WRITE (unit=output_unit, fmt=
"(/,T3,A,/,T3,A,/,T3,A,/)") &
218 "!===========================================================================!", &
219 "! End of TDDFPT driven X-rays absorption spectroscopy calculations !", &
220 "!===========================================================================!"
223 CALL timestop(handle)
232 SUBROUTINE xas_tdp_core(xas_tdp_section, qs_env)
234 TYPE(section_vals_type),
POINTER :: xas_tdp_section
235 TYPE(qs_environment_type),
POINTER :: qs_env
237 CHARACTER(LEN=default_string_length) :: kind_name
238 INTEGER :: batch_size, bo(2), current_state_index, iat, iatom, ibatch, ikind, ispin, istate, &
239 nbatch, nex_atom, output_unit, tmp_index
240 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: batch_atoms, ex_atoms_of_kind
241 INTEGER,
DIMENSION(:),
POINTER :: atoms_of_kind
242 LOGICAL :: do_os, end_of_batch, unique
243 TYPE(admm_type),
POINTER :: admm_env
244 TYPE(atomic_kind_type),
DIMENSION(:),
POINTER :: atomic_kind_set
245 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_ks
246 TYPE(dft_control_type),
POINTER :: dft_control
247 TYPE(donor_state_type),
POINTER :: current_state
248 TYPE(gto_basis_set_type),
POINTER :: tmp_basis
249 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
250 TYPE(xas_atom_env_type),
POINTER :: xas_atom_env
251 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
252 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
254 NULLIFY (xas_tdp_env, xas_tdp_control, atomic_kind_set, atoms_of_kind, current_state)
255 NULLIFY (xas_atom_env, dft_control, matrix_ks, admm_env, qs_kind_set, tmp_basis)
260 IF (output_unit > 0)
THEN
261 WRITE (unit=output_unit, fmt=
"(/,T3,A)") &
262 "# Create and initialize the XAS_TDP environment"
264 CALL get_qs_env(qs_env, dft_control=dft_control)
266 CALL print_info(output_unit, xas_tdp_control, qs_env)
268 IF (output_unit > 0)
THEN
269 IF (xas_tdp_control%check_only)
THEN
270 cpwarn(
"This is a CHECK_ONLY run for donor MOs verification")
275 IF (xas_tdp_control%do_loc)
THEN
276 IF (output_unit > 0)
THEN
277 WRITE (unit=output_unit, fmt=
"(/,T3,A,/)") &
278 "# Localizing core orbitals for better identification"
281 IF (xas_tdp_control%do_uks)
THEN
282 DO ispin = 1, dft_control%nspins
284 xas_tdp_control%print_loc_subsection, myspin=ispin)
288 xas_tdp_control%print_loc_subsection, myspin=1)
293 CALL find_mo_centers(xas_tdp_env, xas_tdp_control, qs_env)
296 CALL assign_mos_to_ex_atoms(xas_tdp_env, xas_tdp_control, qs_env)
299 IF (xas_tdp_control%do_loc)
THEN
300 IF (output_unit > 0)
THEN
301 WRITE (unit=output_unit, fmt=
"(/,T3,A,/,T5,A)") &
302 "# Diagonalize localized MOs wrt the KS matrix in the subspace of each excited", &
303 "atom for better donor state identification."
305 CALL diagonalize_assigned_mo_subset(xas_tdp_env, xas_tdp_control, qs_env)
307 CALL find_mo_centers(xas_tdp_env, xas_tdp_control, qs_env)
310 IF (output_unit > 0)
THEN
311 WRITE (unit=output_unit, fmt=
"(/,T3,A,I4,A,/)") &
312 "# Assign the relevant subset of the ", xas_tdp_control%n_search, &
313 " lowest energy MOs to excited atoms"
315 CALL write_mos_to_ex_atoms_association(xas_tdp_env, xas_tdp_control, qs_env)
318 IF (xas_tdp_control%check_only)
CALL print_checks(xas_tdp_env, xas_tdp_control, qs_env)
322 IF ((xas_tdp_control%do_xc .OR. xas_tdp_control%do_soc .OR. xas_tdp_control%do_gw2x) &
323 .AND. .NOT. xas_tdp_control%check_only)
THEN
325 IF (output_unit > 0 .AND. xas_tdp_control%do_xc)
THEN
326 WRITE (unit=output_unit, fmt=
"(/,T3,A,I4,A)") &
327 "# Integrating the xc kernel on the atomic grids ..."
333 do_os = xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks
335 IF (xas_tdp_control%do_xc .AND. (.NOT. xas_tdp_control%xps_only))
THEN
339 IF (xas_tdp_control%do_soc .OR. xas_tdp_control%do_gw2x)
THEN
347 IF ((.NOT. (xas_tdp_control%check_only .OR. xas_tdp_control%xps_only)) .AND. &
348 (xas_tdp_control%do_xc .OR. xas_tdp_control%do_coulomb))
THEN
349 IF (output_unit > 0)
THEN
350 WRITE (unit=output_unit, fmt=
"(/,T3,A,I4,A)") &
351 "# Computing the RI 3-center Coulomb integrals ..."
359 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
360 current_state_index = 1
363 DO ikind = 1,
SIZE(atomic_kind_set)
365 IF (xas_tdp_control%check_only)
EXIT
366 IF (.NOT. any(xas_tdp_env%ex_kind_indices == ikind)) cycle
368 CALL get_atomic_kind(atomic_kind=atomic_kind_set(ikind), name=kind_name, &
369 atom_list=atoms_of_kind)
373 IF (xas_tdp_control%do_hfx)
THEN
381 CALL get_ri_3c_batches(ex_atoms_of_kind, nbatch, batch_size, atoms_of_kind, xas_tdp_env)
382 nex_atom =
SIZE(ex_atoms_of_kind)
385 DO ibatch = 1, nbatch
387 bo =
get_limit(nex_atom, nbatch, ibatch - 1)
388 batch_size = bo(2) - bo(1) + 1
389 ALLOCATE (batch_atoms(batch_size))
391 DO iat = bo(1), bo(2)
393 batch_atoms(iatom) = ex_atoms_of_kind(iat)
395 CALL sort_unique(batch_atoms, unique)
398 IF (xas_tdp_control%do_hfx)
THEN
399 IF (output_unit > 0)
THEN
400 WRITE (unit=output_unit, fmt=
"(/,T3,A,I4,A,I4,A,I1,A,A)") &
401 "# Computing the RI 3-center Exchange integrals for batch ", ibatch,
"(/", nbatch,
") of ", &
402 batch_size,
" atoms of kind: ", trim(kind_name)
409 DO iat = 1, batch_size
410 iatom = batch_atoms(iat)
412 tmp_index =
locate(xas_tdp_env%ex_atom_indices, iatom)
416 IF (xas_tdp_control%dipole_form ==
xas_dip_len .OR. xas_tdp_control%do_quad)
THEN
417 CALL compute_lenrep_multipole(iatom, xas_tdp_env, xas_tdp_control, qs_env)
421 DO istate = 1,
SIZE(xas_tdp_env%state_types, 1)
423 IF (xas_tdp_env%state_types(istate, tmp_index) ==
xas_not_excited) cycle
425 current_state => xas_tdp_env%donor_states(current_state_index)
427 at_symbol=kind_name, kind_index=ikind, &
428 state_type=xas_tdp_env%state_types(istate, tmp_index))
431 IF (output_unit > 0)
THEN
432 WRITE (unit=output_unit, fmt=
"(/,T3,A,A2,A,I4,A,A,/)") &
433 "# Start of calculations for donor state of type ", &
434 xas_tdp_env%state_type_char(current_state%state_type),
" for atom", &
435 current_state%at_index,
" of kind ", trim(current_state%at_symbol)
440 CALL assign_mos_to_donor_state(current_state, xas_tdp_env, xas_tdp_control, qs_env)
443 CALL perform_mulliken_on_donor_state(current_state, qs_env)
446 IF (xas_tdp_control%do_gw2x)
THEN
447 CALL gw2x_shift(current_state, xas_tdp_env, xas_tdp_control, qs_env)
451 IF (.NOT. xas_tdp_control%xps_only)
THEN
454 IF (xas_tdp_control%do_spin_cons)
THEN
457 CALL compute_dipole_fosc(current_state, xas_tdp_control, xas_tdp_env)
458 IF (xas_tdp_control%do_quad)
CALL compute_quadrupole_fosc(current_state, &
459 xas_tdp_control, xas_tdp_env)
461 xas_tdp_section, qs_env)
462 CALL write_donor_state_restart(
tddfpt_spin_cons, current_state, xas_tdp_section, qs_env)
465 IF (xas_tdp_control%do_spin_flip)
THEN
470 xas_tdp_section, qs_env)
471 CALL write_donor_state_restart(
tddfpt_spin_flip, current_state, xas_tdp_section, qs_env)
474 IF (xas_tdp_control%do_singlet)
THEN
477 CALL compute_dipole_fosc(current_state, xas_tdp_control, xas_tdp_env)
478 IF (xas_tdp_control%do_quad)
CALL compute_quadrupole_fosc(current_state, &
479 xas_tdp_control, xas_tdp_env)
481 xas_tdp_section, qs_env)
482 CALL write_donor_state_restart(
tddfpt_singlet, current_state, xas_tdp_section, qs_env)
485 IF (xas_tdp_control%do_triplet)
THEN
490 xas_tdp_section, qs_env)
491 CALL write_donor_state_restart(
tddfpt_triplet, current_state, xas_tdp_section, qs_env)
495 IF (xas_tdp_control%do_soc .AND. current_state%state_type ==
xas_2p_type)
THEN
496 IF (xas_tdp_control%do_singlet .AND. xas_tdp_control%do_triplet)
THEN
497 CALL include_rcs_soc(current_state, xas_tdp_env, xas_tdp_control, qs_env)
499 IF (xas_tdp_control%do_spin_cons .AND. xas_tdp_control%do_spin_flip)
THEN
500 CALL include_os_soc(current_state, xas_tdp_env, xas_tdp_control, qs_env)
505 CALL print_xas_tdp_to_file(current_state, xas_tdp_env, xas_tdp_control, xas_tdp_section)
507 IF (xas_tdp_control%do_gw2x)
CALL print_xps(current_state, xas_tdp_env, xas_tdp_control, qs_env)
512 current_state_index = current_state_index + 1
513 NULLIFY (current_state)
517 end_of_batch = .false.
518 IF (iat == batch_size) end_of_batch = .true.
521 DEALLOCATE (batch_atoms)
523 DEALLOCATE (ex_atoms_of_kind)
527 IF (dft_control%do_admm)
THEN
528 CALL get_qs_env(qs_env, matrix_ks=matrix_ks, admm_env=admm_env)
529 DO ispin = 1, dft_control%nspins
535 IF (xas_tdp_control%eps_pgf > 0.0_dp)
THEN
536 CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set)
537 DO ikind = 1,
SIZE(atomic_kind_set)
538 CALL get_qs_kind(qs_kind_set(ikind), basis_set=tmp_basis, basis_type=
"ORB")
547 END SUBROUTINE xas_tdp_core
557 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
558 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
559 TYPE(qs_environment_type),
POINTER :: qs_env
561 CHARACTER(LEN=default_string_length) :: kind_name
562 INTEGER :: at_ind, i, ispin, j, k, kind_ind, &
563 n_donor_states, n_kinds, nao, &
564 nat_of_kind, natom, nex_atoms, &
565 nex_kinds, nmatch, nspins
566 INTEGER,
DIMENSION(2) :: homo, n_mo, n_moloc
567 INTEGER,
DIMENSION(:),
POINTER :: ind_of_kind
568 LOGICAL :: do_os, do_uks, unique
570 REAL(
dp),
DIMENSION(:),
POINTER :: mo_evals
571 TYPE(admm_type),
POINTER :: admm_env
572 TYPE(atomic_kind_type),
DIMENSION(:),
POINTER :: at_kind_set
573 TYPE(cell_type),
POINTER :: cell
574 TYPE(cp_fm_type),
POINTER :: mo_coeff
575 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_ks, matrix_s, rho_ao
576 TYPE(dbcsr_type) :: matrix_tmp
577 TYPE(dft_control_type),
POINTER :: dft_control
578 TYPE(gto_basis_set_type),
POINTER :: tmp_basis
579 TYPE(mo_set_type),
DIMENSION(:),
POINTER :: mos
580 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
581 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
582 TYPE(qs_loc_env_type),
POINTER :: qs_loc_env
583 TYPE(qs_rho_type),
POINTER :: rho
584 TYPE(section_type),
POINTER :: dummy_section
585 TYPE(section_vals_type),
POINTER :: loc_section, xas_tdp_section
587 NULLIFY (xas_tdp_section, at_kind_set, ind_of_kind, dft_control, qs_kind_set, tmp_basis)
588 NULLIFY (qs_loc_env, loc_section, mos, particle_set, rho, rho_ao, mo_evals, cell)
589 NULLIFY (mo_coeff, matrix_ks, admm_env, dummy_section)
594 CALL get_qs_env(qs_env, dft_control=dft_control)
599 IF (dft_control%uks) xas_tdp_control%do_uks = .true.
600 IF (dft_control%roks) xas_tdp_control%do_roks = .true.
601 do_uks = xas_tdp_control%do_uks
602 do_os = do_uks .OR. xas_tdp_control%do_roks
611 nex_atoms =
SIZE(xas_tdp_control%list_ex_atoms)
613 ALLOCATE (xas_tdp_env%ex_atom_indices(nex_atoms))
614 ALLOCATE (xas_tdp_env%state_types(
SIZE(xas_tdp_control%state_types, 1), nex_atoms))
615 xas_tdp_env%ex_atom_indices = xas_tdp_control%list_ex_atoms
616 xas_tdp_env%state_types = xas_tdp_control%state_types
620 IF (any(xas_tdp_env%ex_atom_indices > natom))
THEN
621 cpabort(
"Invalid index for the ATOM_LIST keyword.")
625 ALLOCATE (xas_tdp_env%ex_kind_indices(nex_atoms))
626 xas_tdp_env%ex_kind_indices = 0
628 CALL get_qs_env(qs_env, particle_set=particle_set)
630 at_ind = xas_tdp_env%ex_atom_indices(i)
632 IF (all(abs(xas_tdp_env%ex_kind_indices - j) .NE. 0))
THEN
634 xas_tdp_env%ex_kind_indices(k) = j
639 CALL reallocate(xas_tdp_env%ex_kind_indices, 1, nex_kinds)
644 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=at_kind_set)
645 n_kinds =
SIZE(at_kind_set)
648 nex_kinds =
SIZE(xas_tdp_control%list_ex_kinds)
649 ALLOCATE (xas_tdp_env%ex_kind_indices(nex_kinds))
654 natom=nat_of_kind, kind_number=kind_ind)
655 IF (any(xas_tdp_control%list_ex_kinds == kind_name))
THEN
656 nex_atoms = nex_atoms + nat_of_kind
658 xas_tdp_env%ex_kind_indices(k) = kind_ind
662 ALLOCATE (xas_tdp_env%ex_atom_indices(nex_atoms))
663 ALLOCATE (xas_tdp_env%state_types(
SIZE(xas_tdp_control%state_types, 1), nex_atoms))
669 natom=nat_of_kind, atom_list=ind_of_kind)
671 IF (xas_tdp_control%list_ex_kinds(j) == kind_name)
THEN
672 xas_tdp_env%ex_atom_indices(nex_atoms + 1:nex_atoms + nat_of_kind) = ind_of_kind
673 DO k = 1,
SIZE(xas_tdp_control%state_types, 1)
674 xas_tdp_env%state_types(k, nex_atoms + 1:nex_atoms + nat_of_kind) = &
675 xas_tdp_control%state_types(k, j)
677 nex_atoms = nex_atoms + nat_of_kind
683 CALL set_xas_tdp_env(xas_tdp_env, nex_atoms=nex_atoms, nex_kinds=nex_kinds)
686 IF (nmatch .NE.
SIZE(xas_tdp_control%list_ex_kinds))
THEN
687 cpabort(
"Invalid kind(s) for the KIND_LIST keyword.")
693 CALL sort_unique(xas_tdp_env%ex_atom_indices, unique)
694 IF (.NOT. unique)
THEN
695 cpabort(
"Excited atoms not uniquely defined.")
700 IF (all(cell%perd == 0))
THEN
701 xas_tdp_control%is_periodic = .false.
702 ELSE IF (all(cell%perd == 1))
THEN
703 xas_tdp_control%is_periodic = .true.
705 cpabort(
"XAS TDP only implemented for full PBCs or non-PBCs")
710 ALLOCATE (xas_tdp_env%donor_states(n_donor_states))
711 DO i = 1, n_donor_states
716 IF (dft_control%do_admm)
THEN
717 CALL get_qs_env(qs_env, admm_env=admm_env, matrix_ks=matrix_ks)
719 DO ispin = 1, dft_control%nspins
725 IF (xas_tdp_control%eps_pgf > 0.0_dp)
THEN
726 CALL get_qs_env(qs_env, qs_kind_set=qs_kind_set)
728 DO i = 1,
SIZE(qs_kind_set)
729 CALL get_qs_kind(qs_kind_set(i), basis_set=tmp_basis, basis_type=
"ORB")
731 CALL get_qs_kind(qs_kind_set(i), basis_set=tmp_basis, basis_type=
"RI_XAS")
739 CALL get_qs_env(qs_env, mos=mos, matrix_ks=matrix_ks)
740 nspins = 1;
IF (do_uks) nspins = 2
743 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, eigenvalues=mo_evals)
744 CALL calculate_subspace_eigenvalues(mo_coeff, matrix_ks(ispin)%matrix, evals_arg=mo_evals)
753 l_val=xas_tdp_control%do_loc)
756 xas_tdp_control%loc_subsection,
"PRINT")
758 ALLOCATE (xas_tdp_env%qs_loc_env)
760 qs_loc_env => xas_tdp_env%qs_loc_env
761 loc_section => xas_tdp_control%loc_subsection
764 CALL get_mo_set(mos(1), nmo=n_mo(1), homo=homo(1), nao=nao)
768 IF (do_os)
CALL get_mo_set(mos(2), nmo=n_mo(2), homo=homo(2))
769 IF (do_uks) nspins = 2
772 IF (xas_tdp_control%n_search < 0 .OR. xas_tdp_control%n_search > minval(homo)) &
773 xas_tdp_control%n_search = minval(homo)
775 nloc_xas=xas_tdp_control%n_search, spin_xas=1)
779 qs_loc_env%localized_wfn_control%nloc_states(2) = xas_tdp_control%n_search
780 qs_loc_env%localized_wfn_control%lu_bound_states(1, 2) = 1
781 qs_loc_env%localized_wfn_control%lu_bound_states(2, 2) = xas_tdp_control%n_search
785 qs_loc_env%localized_wfn_control%operator_type =
op_loc_berry
786 qs_loc_env%localized_wfn_control%max_iter = 25000
787 IF (.NOT. xas_tdp_control%do_loc)
THEN
788 qs_loc_env%localized_wfn_control%localization_method =
do_loc_none
790 n_moloc = qs_loc_env%localized_wfn_control%nloc_states
791 CALL set_loc_centers(qs_loc_env%localized_wfn_control, n_moloc, nspins)
794 qs_env, do_localize=.true.)
797 qs_env, do_localize=.true., myspin=1)
803 ALLOCATE (xas_tdp_env%mos_of_ex_atoms(xas_tdp_control%n_search, nex_atoms, nspins))
806 IF (do_os) nspins = 2
807 CALL get_qs_env(qs_env, rho=rho, matrix_s=matrix_s)
810 ALLOCATE (xas_tdp_env%q_projector(nspins))
811 ALLOCATE (xas_tdp_env%q_projector(1)%matrix)
812 CALL dbcsr_create(xas_tdp_env%q_projector(1)%matrix, name=
"Q PROJECTOR ALPHA", &
813 template=matrix_s(1)%matrix, matrix_type=dbcsr_type_no_symmetry)
815 ALLOCATE (xas_tdp_env%q_projector(2)%matrix)
816 CALL dbcsr_create(xas_tdp_env%q_projector(2)%matrix, name=
"Q PROJECTOR BETA", &
817 template=matrix_s(1)%matrix, matrix_type=dbcsr_type_no_symmetry)
821 fact = -0.5_dp;
IF (do_os) fact = -1.0_dp
822 CALL dbcsr_multiply(
'N',
'N', fact, matrix_s(1)%matrix, rho_ao(1)%matrix, 0.0_dp, &
823 xas_tdp_env%q_projector(1)%matrix, filter_eps=xas_tdp_control%eps_filter)
824 CALL dbcsr_add_on_diag(xas_tdp_env%q_projector(1)%matrix, 1.0_dp)
825 CALL dbcsr_finalize(xas_tdp_env%q_projector(1)%matrix)
828 CALL dbcsr_multiply(
'N',
'N', fact, matrix_s(1)%matrix, rho_ao(2)%matrix, 0.0_dp, &
829 xas_tdp_env%q_projector(2)%matrix, filter_eps=xas_tdp_control%eps_filter)
830 CALL dbcsr_add_on_diag(xas_tdp_env%q_projector(2)%matrix, 1.0_dp)
831 CALL dbcsr_finalize(xas_tdp_env%q_projector(2)%matrix)
835 ALLOCATE (xas_tdp_env%dipmat(3))
837 ALLOCATE (xas_tdp_env%dipmat(i)%matrix)
838 CALL dbcsr_copy(matrix_tmp, matrix_s(1)%matrix, name=
"XAS TDP dipole matrix")
839 IF (xas_tdp_control%dipole_form ==
xas_dip_vel)
THEN
840 CALL dbcsr_create(xas_tdp_env%dipmat(i)%matrix, template=matrix_s(1)%matrix, &
841 matrix_type=dbcsr_type_antisymmetric)
842 CALL dbcsr_complete_redistribute(matrix_tmp, xas_tdp_env%dipmat(i)%matrix)
844 CALL dbcsr_create(xas_tdp_env%dipmat(i)%matrix, template=matrix_s(1)%matrix, &
845 matrix_type=dbcsr_type_symmetric)
846 CALL dbcsr_copy(xas_tdp_env%dipmat(i)%matrix, matrix_tmp)
848 CALL dbcsr_set(xas_tdp_env%dipmat(i)%matrix, 0.0_dp)
849 CALL dbcsr_release(matrix_tmp)
853 IF (xas_tdp_control%do_quad)
THEN
854 ALLOCATE (xas_tdp_env%quadmat(6))
856 ALLOCATE (xas_tdp_env%quadmat(i)%matrix)
857 CALL dbcsr_copy(xas_tdp_env%quadmat(i)%matrix, matrix_s(1)%matrix, name=
"XAS TDP quadrupole matrix")
858 CALL dbcsr_set(xas_tdp_env%quadmat(i)%matrix, 0.0_dp)
863 IF (xas_tdp_control%dipole_form ==
xas_dip_vel)
THEN
865 CALL p_xyz_ao(xas_tdp_env%dipmat, qs_env, minimum_image=.true.)
869 IF (xas_tdp_control%do_soc .OR. xas_tdp_control%do_gw2x)
THEN
870 ALLOCATE (xas_tdp_env%orb_soc(3))
872 ALLOCATE (xas_tdp_env%orb_soc(i)%matrix)
877 CALL safety_check(xas_tdp_control, qs_env)
883 IF (xas_tdp_control%do_ot .OR. xas_tdp_control%do_gw2x)
THEN
884 CALL make_lumo_guess(xas_tdp_env, xas_tdp_control, qs_env)
897 SUBROUTINE get_ri_3c_batches(ex_atoms_of_kind, nbatch, batch_size, atoms_of_kind, xas_tdp_env)
899 INTEGER,
ALLOCATABLE,
DIMENSION(:),
INTENT(INOUT) :: ex_atoms_of_kind
900 INTEGER,
INTENT(OUT) :: nbatch
901 INTEGER,
INTENT(IN) :: batch_size
902 INTEGER,
DIMENSION(:),
INTENT(IN) :: atoms_of_kind
903 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
905 INTEGER :: iat, iatom, nex_atom
906 TYPE(rng_stream_type),
ALLOCATABLE :: rng_stream
910 DO iat = 1,
SIZE(atoms_of_kind)
911 iatom = atoms_of_kind(iat)
912 IF (.NOT. any(xas_tdp_env%ex_atom_indices == iatom)) cycle
913 nex_atom = nex_atom + 1
916 ALLOCATE (ex_atoms_of_kind(nex_atom))
918 DO iat = 1,
SIZE(atoms_of_kind)
919 iatom = atoms_of_kind(iat)
920 IF (.NOT. any(xas_tdp_env%ex_atom_indices == iatom)) cycle
921 nex_atom = nex_atom + 1
922 ex_atoms_of_kind(nex_atom) = iatom
926 rng_stream = rng_stream_type(name=
"uniform_rng", distribution_type=
uniform)
927 CALL rng_stream%shuffle(ex_atoms_of_kind(1:nex_atom))
929 nbatch = nex_atom/batch_size
930 IF (nbatch*batch_size .NE. nex_atom) nbatch = nbatch + 1
932 END SUBROUTINE get_ri_3c_batches
939 SUBROUTINE safety_check(xas_tdp_control, qs_env)
941 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
942 TYPE(qs_environment_type),
POINTER :: qs_env
944 TYPE(dft_control_type),
POINTER :: dft_control
947 IF (xas_tdp_control%is_periodic .AND. xas_tdp_control%do_hfx &
949 cpabort(
"XAS TDP with Coulomb operator for exact exchange only supports non-periodic BCs")
953 IF (xas_tdp_control%do_roks .OR. xas_tdp_control%do_uks)
THEN
955 IF (.NOT. (xas_tdp_control%do_spin_cons .OR. xas_tdp_control%do_spin_flip))
THEN
956 cpabort(
"Need spin-conserving and/or spin-flip excitations for open-shell systems")
959 IF (xas_tdp_control%do_singlet .OR. xas_tdp_control%do_triplet)
THEN
960 cpabort(
"Singlet/triplet excitations only for restricted closed-shell systems")
963 IF (xas_tdp_control%do_soc .AND. .NOT. &
964 (xas_tdp_control%do_spin_flip .AND. xas_tdp_control%do_spin_cons))
THEN
966 cpabort(
"Both spin-conserving and spin-flip excitations are required for SOC")
970 IF (.NOT. (xas_tdp_control%do_singlet .OR. xas_tdp_control%do_triplet))
THEN
971 cpabort(
"Need singlet and/or triplet excitations for closed-shell systems")
974 IF (xas_tdp_control%do_spin_cons .OR. xas_tdp_control%do_spin_flip)
THEN
975 cpabort(
"Spin-conserving/spin-flip excitations only for open-shell systems")
978 IF (xas_tdp_control%do_soc .AND. .NOT. &
979 (xas_tdp_control%do_singlet .AND. xas_tdp_control%do_triplet))
THEN
981 cpabort(
"Both singlet and triplet excitations are needed for SOC")
986 IF (xas_tdp_control%do_soc .AND. xas_tdp_control%e_range > 0.0_dp)
THEN
987 cpwarn(
"Using E_RANGE and SOC together may lead to crashes, use N_EXCITED for safety.")
991 IF (.NOT. xas_tdp_control%tamm_dancoff)
THEN
993 IF (xas_tdp_control%do_spin_flip)
THEN
994 cpabort(
"Spin-flip kernel only implemented for Tamm-Dancoff approximation")
997 IF (xas_tdp_control%do_ot)
THEN
998 cpabort(
"OT diagonalization only available within the Tamm-Dancoff approximation")
1003 IF (xas_tdp_control%do_gw2x)
THEN
1004 IF (.NOT. xas_tdp_control%do_hfx)
THEN
1005 cpabort(
"GW2x requires the definition of the EXACT_EXCHANGE kernel")
1007 IF (.NOT. xas_tdp_control%do_loc)
THEN
1008 cpabort(
"GW2X requires the LOCALIZE keyword in DONOR_STATES")
1013 CALL get_qs_env(qs_env, dft_control=dft_control)
1014 IF (dft_control%do_admm)
THEN
1019 cpabort(
"XAS_TDP only compatible with ADMM purification NONE, CAUCHY_SUBSPACE and MO_DIAG")
1024 END SUBROUTINE safety_check
1032 SUBROUTINE print_info(ou, xas_tdp_control, qs_env)
1034 INTEGER,
INTENT(IN) :: ou
1035 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
1036 TYPE(qs_environment_type),
POINTER :: qs_env
1040 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_s
1041 TYPE(dft_control_type),
POINTER :: dft_control
1042 TYPE(section_vals_type),
POINTER :: input, kernel_section
1044 NULLIFY (input, kernel_section, dft_control, matrix_s)
1046 CALL get_qs_env(qs_env, input=input, dft_control=dft_control, matrix_s=matrix_s)
1049 occ = dbcsr_get_occupation(matrix_s(1)%matrix)
1051 IF (ou .LE. 0)
RETURN
1054 IF (xas_tdp_control%do_uks)
THEN
1055 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1056 "XAS_TDP| Reference calculation: Unrestricted Kohn-Sham"
1057 ELSE IF (xas_tdp_control%do_roks)
THEN
1058 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1059 "XAS_TDP| Reference calculation: Restricted Open-Shell Kohn-Sham"
1061 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1062 "XAS_TDP| Reference calculation: Restricted Closed-Shell Kohn-Sham"
1066 IF (xas_tdp_control%tamm_dancoff)
THEN
1067 WRITE (unit=ou, fmt=
"(T3,A)") &
1068 "XAS_TDP| Tamm-Dancoff Approximation (TDA): On"
1070 WRITE (unit=ou, fmt=
"(T3,A)") &
1071 "XAS_TDP| Tamm-Dancoff Approximation (TDA): Off"
1075 IF (xas_tdp_control%dipole_form ==
xas_dip_vel)
THEN
1076 WRITE (unit=ou, fmt=
"(T3,A)") &
1077 "XAS_TDP| Transition Dipole Representation: VELOCITY"
1079 WRITE (unit=ou, fmt=
"(T3,A)") &
1080 "XAS_TDP| Transition Dipole Representation: LENGTH"
1084 IF (xas_tdp_control%do_quad)
THEN
1085 WRITE (unit=ou, fmt=
"(T3,A)") &
1086 "XAS_TDP| Transition Quadrupole: On"
1090 IF (xas_tdp_control%eps_pgf > 0.0_dp)
THEN
1091 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1092 "XAS_TDP| EPS_PGF_XAS: ", xas_tdp_control%eps_pgf
1094 WRITE (unit=ou, fmt=
"(T3,A,ES7.1,A)") &
1095 "XAS_TDP| EPS_PGF_XAS: ", dft_control%qs_control%eps_pgf_orb,
" (= EPS_PGF_ORB)"
1099 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1100 "XAS_TDP| EPS_FILTER: ", xas_tdp_control%eps_filter
1103 IF (xas_tdp_control%do_xc)
THEN
1104 WRITE (unit=ou, fmt=
"(T3,A)") &
1105 "XAS_TDP| Radial Grid(s) Info: Kind, na, nr"
1106 DO i = 1,
SIZE(xas_tdp_control%grid_info, 1)
1107 WRITE (unit=ou, fmt=
"(T3,A,A6,A,A,A,A)") &
1108 " ", trim(xas_tdp_control%grid_info(i, 1)),
", ", &
1109 trim(xas_tdp_control%grid_info(i, 2)),
", ", trim(xas_tdp_control%grid_info(i, 3))
1114 IF (.NOT. xas_tdp_control%do_coulomb)
THEN
1115 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1116 "XAS_TDP| No kernel (standard DFT)"
1120 IF (xas_tdp_control%do_xc)
THEN
1122 WRITE (unit=ou, fmt=
"(/,T3,A,F5.2,A)") &
1123 "XAS_TDP| RI Region's Radius: ", xas_tdp_control%ri_radius*
angstrom,
" Ang"
1125 WRITE (unit=ou, fmt=
"(T3,A,/)") &
1126 "XAS_TDP| XC Kernel Functional(s) used for the kernel:"
1129 CALL xc_write(ou, kernel_section, lsd=.true.)
1133 IF (xas_tdp_control%do_hfx)
THEN
1134 WRITE (unit=ou, fmt=
"(/,T3,A,/,/,T3,A,F5.3)") &
1135 "XAS_TDP| Exact Exchange Kernel: Yes ", &
1136 "EXACT_EXCHANGE| Scale: ", xas_tdp_control%sx
1138 WRITE (unit=ou, fmt=
"(T3,A)") &
1139 "EXACT_EXCHANGE| Potential : Coulomb"
1141 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,A)") &
1142 "EXACT_EXCHANGE| Potential: Truncated Coulomb", &
1143 "EXACT_EXCHANGE| Range: ", xas_tdp_control%x_potential%cutoff_radius*
angstrom,
", (Ang)", &
1144 "EXACT_EXCHANGE| T_C_G_DATA: ", trim(xas_tdp_control%x_potential%filename)
1146 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,F5.2,A,/,T3,A,ES7.1)") &
1147 "EXACT_EXCHANGE| Potential: Short Range", &
1148 "EXACT_EXCHANGE| Omega: ", xas_tdp_control%x_potential%omega,
", (1/a0)", &
1149 "EXACT_EXCHANGE| Effective Range: ", xas_tdp_control%x_potential%cutoff_radius*
angstrom,
", (Ang)", &
1150 "EXACT_EXCHANGE| EPS_RANGE: ", xas_tdp_control%eps_range
1152 IF (xas_tdp_control%eps_screen > 1.0e-16)
THEN
1153 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1154 "EXACT_EXCHANGE| EPS_SCREENING: ", xas_tdp_control%eps_screen
1158 IF (xas_tdp_control%do_ri_metric)
THEN
1160 WRITE (unit=ou, fmt=
"(/,T3,A)") &
1161 "EXACT_EXCHANGE| Using a RI metric"
1162 IF (xas_tdp_control%ri_m_potential%potential_type ==
do_potential_id)
THEN
1163 WRITE (unit=ou, fmt=
"(T3,A)") &
1164 "EXACT_EXCHANGE RI_METRIC| Potential : Overlap"
1166 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,A)") &
1167 "EXACT_EXCHANGE RI_METRIC| Potential: Truncated Coulomb", &
1168 "EXACT_EXCHANGE RI_METRIC| Range: ", xas_tdp_control%ri_m_potential%cutoff_radius &
1170 "EXACT_EXCHANGE RI_METRIC| T_C_G_DATA: ", trim(xas_tdp_control%ri_m_potential%filename)
1172 WRITE (unit=ou, fmt=
"(T3,A,/,T3,A,F5.2,A,/,T3,A,F5.2,A,/,T3,A,ES7.1)") &
1173 "EXACT_EXCHANGE RI_METRIC| Potential: Short Range", &
1174 "EXACT_EXCHANGE RI_METRIC| Omega: ", xas_tdp_control%ri_m_potential%omega,
", (1/a0)", &
1175 "EXACT_EXCHANGE RI_METRIC| Effective Range: ", &
1176 xas_tdp_control%ri_m_potential%cutoff_radius*
angstrom,
", (Ang)", &
1177 "EXACT_EXCHANGE RI_METRIC| EPS_RANGE: ", xas_tdp_control%eps_range
1181 WRITE (unit=ou, fmt=
"(/,T3,A,/)") &
1182 "XAS_TDP| Exact Exchange Kernel: No "
1186 WRITE (unit=ou, fmt=
"(/,T3,A,F5.2)") &
1187 "XAS_TDP| Overlap matrix occupation: ", occ
1190 IF (xas_tdp_control%do_gw2x)
THEN
1191 WRITE (unit=ou, fmt=
"(T3,A,/)") &
1192 "XAS_TDP| GW2X correction enabled"
1194 IF (xas_tdp_control%xps_only)
THEN
1195 WRITE (unit=ou, fmt=
"(T3,A)") &
1196 "GW2X| Only computing ionizations potentials for XPS"
1199 IF (xas_tdp_control%pseudo_canonical)
THEN
1200 WRITE (unit=ou, fmt=
"(T3,A)") &
1201 "GW2X| Using the pseudo-canonical scheme"
1203 WRITE (unit=ou, fmt=
"(T3,A)") &
1204 "GW2X| Using the GW2X* scheme"
1207 WRITE (unit=ou, fmt=
"(T3,A,ES7.1)") &
1208 "GW2X| EPS_GW2X: ", xas_tdp_control%gw2x_eps
1210 WRITE (unit=ou, fmt=
"(T3,A,I5)") &
1211 "GW2X| contraction batch size: ", xas_tdp_control%batch_size
1213 IF ((int(xas_tdp_control%c_os) .NE. 1) .OR. (int(xas_tdp_control%c_ss) .NE. 1))
THEN
1214 WRITE (unit=ou, fmt=
"(T3,A,F7.4,/,T3,A,F7.4)") &
1215 "GW2X| Same-spin scaling factor: ", xas_tdp_control%c_ss, &
1216 "GW2X| Opposite-spin scaling factor: ", xas_tdp_control%c_os
1221 END SUBROUTINE print_info
1236 SUBROUTINE assign_mos_to_ex_atoms(xas_tdp_env, xas_tdp_control, qs_env)
1238 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
1239 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
1240 TYPE(qs_environment_type),
POINTER :: qs_env
1242 INTEGER :: at_index, iat, iat_memo, imo, ispin, &
1243 n_atoms, n_search, nex_atoms, nspins
1244 INTEGER,
DIMENSION(3) :: perd_init
1245 INTEGER,
DIMENSION(:, :, :),
POINTER :: mos_of_ex_atoms
1246 REAL(
dp) :: dist, dist_min
1247 REAL(
dp),
DIMENSION(3) :: at_pos, r_ac, wfn_center
1248 TYPE(cell_type),
POINTER :: cell
1249 TYPE(localized_wfn_control_type),
POINTER :: localized_wfn_control
1250 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
1252 NULLIFY (localized_wfn_control, mos_of_ex_atoms, cell, particle_set)
1255 mos_of_ex_atoms => xas_tdp_env%mos_of_ex_atoms
1256 mos_of_ex_atoms(:, :, :) = -1
1257 n_search = xas_tdp_control%n_search
1258 nex_atoms = xas_tdp_env%nex_atoms
1259 localized_wfn_control => xas_tdp_env%qs_loc_env%localized_wfn_control
1260 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, cell=cell)
1261 n_atoms =
SIZE(particle_set)
1262 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1265 perd_init = cell%perd
1269 DO ispin = 1, nspins
1270 DO imo = 1, n_search
1272 wfn_center(1:3) = localized_wfn_control%centers_set(ispin)%array(1:3, imo)
1276 dist_min = 10000.0_dp
1278 at_pos = particle_set(iat)%r
1279 r_ac =
pbc(at_pos, wfn_center, cell)
1283 IF (dist < dist_min)
THEN
1290 IF (any(xas_tdp_env%ex_atom_indices == iat_memo))
THEN
1291 at_index =
locate(xas_tdp_env%ex_atom_indices, iat_memo)
1292 mos_of_ex_atoms(imo, at_index, ispin) = 1
1298 cell%perd = perd_init
1300 END SUBROUTINE assign_mos_to_ex_atoms
1312 SUBROUTINE reinit_qs_loc_env(qs_loc_env, n_loc_states, do_uks, qs_env)
1314 TYPE(qs_loc_env_type),
POINTER :: qs_loc_env
1315 INTEGER,
INTENT(IN) :: n_loc_states
1316 LOGICAL,
INTENT(IN) :: do_uks
1317 TYPE(qs_environment_type),
POINTER :: qs_env
1319 INTEGER :: i, nspins
1320 TYPE(localized_wfn_control_type),
POINTER :: loc_wfn_control
1328 loc_wfn_control => qs_loc_env%localized_wfn_control
1333 loc_wfn_control%nloc_states(:) = n_loc_states
1334 loc_wfn_control%eps_occ = 0.0_dp
1335 loc_wfn_control%lu_bound_states(1, :) = 1
1336 loc_wfn_control%lu_bound_states(2, :) = n_loc_states
1338 loc_wfn_control%do_homo = .true.
1339 ALLOCATE (loc_wfn_control%loc_states(n_loc_states, 2))
1340 DO i = 1, n_loc_states
1341 loc_wfn_control%loc_states(i, :) = i
1344 nspins = 1;
IF (do_uks) nspins = 2
1345 CALL set_loc_centers(loc_wfn_control, loc_wfn_control%nloc_states, nspins=nspins)
1348 CALL qs_loc_env_init(qs_loc_env, loc_wfn_control, qs_env, do_localize=.true.)
1350 CALL qs_loc_env_init(qs_loc_env, loc_wfn_control, qs_env, myspin=1, do_localize=.true.)
1353 END SUBROUTINE reinit_qs_loc_env
1363 SUBROUTINE diagonalize_assigned_mo_subset(xas_tdp_env, xas_tdp_control, qs_env)
1365 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
1366 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
1367 TYPE(qs_environment_type),
POINTER :: qs_env
1369 INTEGER :: i, iat, ilmo, ispin, nao, nlmo, nspins
1370 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: evals
1371 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
1372 TYPE(cp_fm_struct_type),
POINTER :: ks_struct, lmo_struct
1373 TYPE(cp_fm_type) :: evecs, ks_fm, lmo_fm, work
1374 TYPE(cp_fm_type),
POINTER :: mo_coeff
1375 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_ks
1376 TYPE(mo_set_type),
DIMENSION(:),
POINTER :: mos
1377 TYPE(mp_para_env_type),
POINTER :: para_env
1379 NULLIFY (mos, mo_coeff, matrix_ks, para_env, blacs_env, lmo_struct, ks_struct)
1382 CALL get_qs_env(qs_env, mos=mos, matrix_ks=matrix_ks, para_env=para_env, blacs_env=blacs_env)
1384 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1387 DO ispin = 1, nspins
1388 DO iat = 1, xas_tdp_env%nex_atoms
1391 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, nao=nao)
1394 nlmo = count(xas_tdp_env%mos_of_ex_atoms(:, iat, ispin) == 1)
1396 para_env=para_env, context=blacs_env)
1401 para_env=para_env, context=blacs_env)
1407 DO ilmo = 1, xas_tdp_control%n_search
1408 IF (xas_tdp_env%mos_of_ex_atoms(ilmo, iat, ispin) == -1) cycle
1413 s_firstcol=ilmo, t_firstrow=1, t_firstcol=i)
1419 CALL parallel_gemm(
'T',
'N', nlmo, nlmo, nao, 1.0_dp, lmo_fm, work, 0.0_dp, ks_fm)
1422 ALLOCATE (evals(nlmo))
1427 CALL parallel_gemm(
'N',
'N', nao, nlmo, nlmo, 1.0_dp, lmo_fm, evecs, 0.0_dp, work)
1431 DO ilmo = 1, xas_tdp_control%n_search
1432 IF (xas_tdp_env%mos_of_ex_atoms(ilmo, iat, ispin) == -1) cycle
1436 s_firstcol=i, t_firstrow=1, t_firstcol=ilmo)
1441 CALL cp_fm_release(lmo_fm)
1442 CALL cp_fm_release(work)
1444 CALL cp_fm_release(ks_fm)
1445 CALL cp_fm_release(evecs)
1450 END SUBROUTINE diagonalize_assigned_mo_subset
1461 SUBROUTINE assign_mos_to_donor_state(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
1463 TYPE(donor_state_type),
POINTER :: donor_state
1464 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
1465 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
1466 TYPE(qs_environment_type),
POINTER :: qs_env
1468 INTEGER :: at_index, i, iat, imo, ispin, l, my_mo, &
1469 n_search, n_states, nao, ndo_so, nj, &
1470 nsgf_kind, nsgf_sto, nspins, &
1472 INTEGER,
ALLOCATABLE,
DIMENSION(:, :) :: my_mos
1473 INTEGER,
DIMENSION(2) :: next_best_overlap_ind
1474 INTEGER,
DIMENSION(4, 7) :: ne
1475 INTEGER,
DIMENSION(:),
POINTER :: first_sgf, lq, nq
1476 INTEGER,
DIMENSION(:, :, :),
POINTER :: mos_of_ex_atoms
1479 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: diag, overlap, sto_overlap
1480 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: max_overlap
1481 REAL(
dp),
DIMENSION(2) :: next_best_overlap
1482 REAL(
dp),
DIMENSION(:),
POINTER :: mo_evals, zeta
1483 REAL(
dp),
DIMENSION(:, :),
POINTER :: overlap_matrix, tmp_coeff
1484 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
1485 TYPE(cp_fm_struct_type),
POINTER :: eval_mat_struct, gs_struct
1486 TYPE(cp_fm_type) :: eval_mat, work_mat
1487 TYPE(cp_fm_type),
POINTER :: gs_coeffs, mo_coeff
1488 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_ks
1489 TYPE(gto_basis_set_type),
POINTER :: kind_basis_set, sto_to_gto_basis_set
1490 TYPE(mo_set_type),
DIMENSION(:),
POINTER :: mos
1491 TYPE(mp_para_env_type),
POINTER :: para_env
1492 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
1493 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
1494 TYPE(sto_basis_set_type),
POINTER :: sto_basis_set
1496 NULLIFY (sto_basis_set, sto_to_gto_basis_set, qs_kind_set, kind_basis_set, lq, nq, zeta)
1497 NULLIFY (overlap_matrix, mos, mo_coeff, mos_of_ex_atoms, tmp_coeff, first_sgf, particle_set)
1498 NULLIFY (mo_evals, matrix_ks, para_env, blacs_env)
1499 NULLIFY (eval_mat_struct, gs_struct, gs_coeffs)
1503 CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set, mos=mos, particle_set=particle_set, &
1504 matrix_ks=matrix_ks, para_env=para_env, blacs_env=blacs_env)
1506 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1517 ELSE IF (donor_state%state_type ==
xas_2s_type)
THEN
1521 ELSE IF (donor_state%state_type ==
xas_2p_type)
THEN
1526 cpabort(
"Procedure for required type not implemented")
1528 ALLOCATE (my_mos(n_states, nspins))
1529 ALLOCATE (max_overlap(n_states, nspins))
1532 CALL get_qs_kind(qs_kind_set(donor_state%kind_index), zeff=zeff)
1540 ne(l, i) =
ptable(zval)%e_conv(l - 1) - 2*nj*(i - l)
1541 ne(l, i) = max(ne(l, i), 0)
1542 ne(l, i) = min(ne(l, i), 2*nj)
1547 zeta(1) =
srules(zval, ne, nq(1), lq(1))
1554 DEALLOCATE (nq, lq, zeta)
1558 gto_basis_set=sto_to_gto_basis_set, &
1560 sto_to_gto_basis_set%norm_type = 2
1564 CALL get_qs_kind(qs_kind_set(donor_state%kind_index), basis_set=kind_basis_set)
1569 ALLOCATE (overlap_matrix(nsgf_sto, nsgf_kind))
1579 mos_of_ex_atoms => xas_tdp_env%mos_of_ex_atoms
1580 n_search = xas_tdp_control%n_search
1581 at_index = donor_state%at_index
1582 iat =
locate(xas_tdp_env%ex_atom_indices, at_index)
1583 ALLOCATE (first_sgf(
SIZE(particle_set)))
1584 CALL get_particle_set(particle_set=particle_set, qs_kind_set=qs_kind_set, first_sgf=first_sgf)
1585 ALLOCATE (tmp_coeff(nsgf_kind, 1))
1586 ALLOCATE (sto_overlap(nsgf_kind))
1587 ALLOCATE (overlap(n_search))
1589 next_best_overlap = 0.0_dp
1590 max_overlap = 0.0_dp
1592 DO ispin = 1, nspins
1594 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff, nao=nao)
1598 DO imo = 1, n_search
1599 IF (mos_of_ex_atoms(imo, iat, ispin) > 0)
THEN
1601 sto_overlap = 0.0_dp
1605 CALL cp_fm_get_submatrix(fm=mo_coeff, target_m=tmp_coeff, start_row=first_sgf(at_index), &
1606 start_col=imo, n_rows=nsgf_kind, n_cols=1, transpose=.false.)
1609 CALL dgemm(
'N',
'N', nsgf_sto, 1, nsgf_kind, 1.0_dp, overlap_matrix, nsgf_sto, &
1610 tmp_coeff, nsgf_kind, 0.0_dp, sto_overlap, nsgf_sto)
1615 overlap(imo) = sum(abs(sto_overlap))
1622 my_mo = maxloc(overlap, 1)
1623 my_mos(i, ispin) = my_mo
1624 max_overlap(i, ispin) = maxval(overlap, 1)
1625 overlap(my_mo) = 0.0_dp
1628 next_best_overlap(ispin) = maxval(overlap, 1)
1629 next_best_overlap_ind(ispin) = maxloc(overlap, 1)
1632 CALL sort_unique(my_mos(:, ispin), unique)
1637 DEALLOCATE (overlap_matrix, tmp_coeff)
1640 IF (all(my_mos > 0) .AND. all(my_mos <= n_search))
THEN
1642 ALLOCATE (donor_state%mo_indices(n_states, nspins))
1643 donor_state%mo_indices = my_mos
1644 donor_state%ndo_mo = n_states
1648 para_env=para_env, context=blacs_env)
1649 ALLOCATE (donor_state%gs_coeffs)
1652 DO ispin = 1, nspins
1653 CALL get_mo_set(mos(ispin), mo_coeff=mo_coeff)
1656 ncol=1, s_firstrow=1, s_firstcol=my_mos(i, ispin), &
1657 t_firstrow=1, t_firstcol=(ispin - 1)*n_states + i)
1660 gs_coeffs => donor_state%gs_coeffs
1663 ALLOCATE (donor_state%contract_coeffs(nsgf_kind, n_states*nspins))
1664 CALL cp_fm_get_submatrix(gs_coeffs, donor_state%contract_coeffs, start_row=first_sgf(at_index), &
1665 start_col=1, n_rows=nsgf_kind, n_cols=n_states*nspins)
1670 IF (.NOT. xas_tdp_control%do_loc .AND. .NOT. xas_tdp_control%do_roks)
THEN
1671 IF (output_unit > 0)
THEN
1672 WRITE (unit=output_unit, fmt=
"(T5,A,/,T5,A,/,T5,A)") &
1673 "The following canonical MO(s) have been associated with the donor state(s)", &
1674 "based on the overlap with the components of a minimal STO basis: ", &
1675 " Spin MO index overlap(sum)"
1678 ALLOCATE (donor_state%energy_evals(n_states, nspins))
1679 donor_state%energy_evals = 0.0_dp
1682 DO ispin = 1, nspins
1683 CALL get_mo_set(mos(ispin), eigenvalues=mo_evals)
1685 donor_state%energy_evals(i, ispin) = mo_evals(my_mos(i, ispin))
1687 IF (output_unit > 0)
THEN
1688 WRITE (unit=output_unit, fmt=
"(T46,I4,I11,F17.5)") &
1689 ispin, my_mos(i, ispin), max_overlap(i, ispin)
1697 IF (output_unit > 0)
THEN
1698 WRITE (unit=output_unit, fmt=
"(T5,A,/,T5,A,/,T5,A)") &
1699 "The following localized MO(s) have been associated with the donor state(s)", &
1700 "based on the overlap with the components of a minimal STO basis: ", &
1701 " Spin MO index overlap(sum)"
1705 DO ispin = 1, nspins
1709 IF (output_unit > 0)
THEN
1710 WRITE (unit=output_unit, fmt=
"(T46,I4,I11,F17.5)") &
1711 ispin, my_mos(i, ispin), max_overlap(i, ispin)
1719 ndo_so = nspins*n_states
1722 para_env=para_env, context=blacs_env)
1724 ALLOCATE (diag(ndo_so))
1726 IF (.NOT. xas_tdp_control%do_roks)
THEN
1728 ALLOCATE (donor_state%energy_evals(n_states, nspins))
1729 donor_state%energy_evals = 0.0_dp
1732 DO ispin = 1, nspins
1734 CALL parallel_gemm(
'T',
'N', ndo_so, ndo_so, nao, 1.0_dp, gs_coeffs, work_mat, 0.0_dp, eval_mat)
1738 donor_state%energy_evals(:, ispin) = diag((ispin - 1)*n_states + 1:ispin*n_states)
1744 ALLOCATE (donor_state%energy_evals(n_states, 2))
1745 donor_state%energy_evals = 0.0_dp
1750 CALL parallel_gemm(
'T',
'N', ndo_so, ndo_so, nao, 1.0_dp, gs_coeffs, work_mat, 0.0_dp, eval_mat)
1753 donor_state%energy_evals(:, ispin) = diag(:)
1761 CALL cp_fm_release(work_mat)
1762 CALL cp_fm_release(eval_mat)
1768 ALLOCATE (donor_state%gw2x_evals(
SIZE(donor_state%energy_evals, 1),
SIZE(donor_state%energy_evals, 2)))
1769 donor_state%gw2x_evals(:, :) = donor_state%energy_evals(:, :)
1773 DEALLOCATE (first_sgf)
1775 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T5,A)")
" "
1777 DO ispin = 1, nspins
1778 IF (output_unit > 0)
THEN
1779 WRITE (unit=output_unit, fmt=
"(T5,A,I1,A,F7.5,A,I4)") &
1780 "The next best overlap for spin ", ispin,
" is ", next_best_overlap(ispin), &
1781 " for MO with index ", next_best_overlap_ind(ispin)
1784 IF (output_unit > 0)
WRITE (unit=output_unit, fmt=
"(T5,A)")
" "
1787 cpabort(
"A core donor state could not be assigned MO(s). Increasing NSEARCH might help.")
1790 END SUBROUTINE assign_mos_to_donor_state
1800 SUBROUTINE find_mo_centers(xas_tdp_env, xas_tdp_control, qs_env)
1802 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
1803 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
1804 TYPE(qs_environment_type),
POINTER :: qs_env
1806 INTEGER :: dim_op, i, ispin, j, n_centers, nao, &
1808 REAL(
dp),
DIMENSION(6) :: weights
1809 TYPE(cell_type),
POINTER :: cell
1810 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
1811 TYPE(cp_fm_struct_type),
POINTER :: tmp_fm_struct
1812 TYPE(cp_fm_type) :: opvec
1813 TYPE(cp_fm_type),
ALLOCATABLE,
DIMENSION(:, :) :: zij_fm_set
1814 TYPE(cp_fm_type),
DIMENSION(:),
POINTER :: moloc_coeff
1815 TYPE(cp_fm_type),
POINTER :: vectors
1816 TYPE(dbcsr_p_type),
DIMENSION(:, :),
POINTER :: op_sm_set
1817 TYPE(mp_para_env_type),
POINTER :: para_env
1818 TYPE(qs_loc_env_type),
POINTER :: qs_loc_env
1819 TYPE(section_vals_type),
POINTER :: print_loc_section, prog_run_info
1821 NULLIFY (qs_loc_env, cell, print_loc_section, op_sm_set, moloc_coeff, vectors)
1822 NULLIFY (tmp_fm_struct, para_env, blacs_env, prog_run_info)
1825 print_loc_section => xas_tdp_control%print_loc_subsection
1826 n_centers = xas_tdp_control%n_search
1827 CALL get_qs_env(qs_env=qs_env, para_env=para_env, blacs_env=blacs_env, cell=cell)
1835 CALL reinit_qs_loc_env(xas_tdp_env%qs_loc_env, n_centers, xas_tdp_control%do_uks, qs_env)
1836 qs_loc_env => xas_tdp_env%qs_loc_env
1839 CALL get_qs_loc_env(qs_loc_env=qs_loc_env, weights=weights, op_sm_set=op_sm_set, &
1840 moloc_coeff=moloc_coeff)
1843 vectors => moloc_coeff(1)
1848 ncol_global=n_centers, nrow_global=n_centers)
1850 IF (cell%orthorhombic)
THEN
1855 ALLOCATE (zij_fm_set(2, dim_op))
1863 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
1865 DO ispin = 1, nspins
1867 vectors => moloc_coeff(ispin)
1872 CALL parallel_gemm(
"T",
"N", n_centers, n_centers, nao, 1.0_dp, vectors, opvec, 0.0_dp, &
1879 cell=cell, weights=weights, ispin=ispin, &
1880 print_loc_section=print_loc_section, only_initial_out=.true.)
1884 CALL cp_fm_release(opvec)
1886 CALL cp_fm_release(zij_fm_set)
1889 qs_loc_env%do_localize = xas_tdp_control%do_loc
1891 END SUBROUTINE find_mo_centers
1900 SUBROUTINE print_checks(xas_tdp_env, xas_tdp_control, qs_env)
1902 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
1903 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
1904 TYPE(qs_environment_type),
POINTER :: qs_env
1906 CHARACTER(LEN=default_string_length) :: kind_name
1907 INTEGER :: current_state_index, iat, iatom, ikind, &
1908 istate, output_unit, tmp_index
1909 INTEGER,
DIMENSION(:),
POINTER :: atoms_of_kind
1910 TYPE(atomic_kind_type),
DIMENSION(:),
POINTER :: atomic_kind_set
1911 TYPE(donor_state_type),
POINTER :: current_state
1913 NULLIFY (atomic_kind_set, atoms_of_kind, current_state)
1917 IF (output_unit > 0)
THEN
1918 WRITE (output_unit,
"(/,T3,A,/,T3,A,/,T3,A)") &
1919 "# Check the donor states for their quality. They need to have a well defined type ", &
1920 " (1s, 2s, etc) which is indicated by the overlap. They also need to be localized, ", &
1921 " for which the Mulliken population analysis is one indicator (must be close to 1.0)"
1925 CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
1926 current_state_index = 1
1929 DO ikind = 1,
SIZE(atomic_kind_set)
1931 CALL get_atomic_kind(atomic_kind=atomic_kind_set(ikind), name=kind_name, &
1932 atom_list=atoms_of_kind)
1934 IF (.NOT. any(xas_tdp_env%ex_kind_indices == ikind)) cycle
1937 DO iat = 1,
SIZE(atoms_of_kind)
1938 iatom = atoms_of_kind(iat)
1940 IF (.NOT. any(xas_tdp_env%ex_atom_indices == iatom)) cycle
1941 tmp_index =
locate(xas_tdp_env%ex_atom_indices, iatom)
1944 DO istate = 1,
SIZE(xas_tdp_env%state_types, 1)
1946 IF (xas_tdp_env%state_types(istate, tmp_index) ==
xas_not_excited) cycle
1948 current_state => xas_tdp_env%donor_states(current_state_index)
1950 at_symbol=kind_name, kind_index=ikind, &
1951 state_type=xas_tdp_env%state_types(istate, tmp_index))
1953 IF (output_unit > 0)
THEN
1954 WRITE (output_unit,
"(/,T4,A,A2,A,I4,A,A,A)") &
1955 "-Donor state of type ", xas_tdp_env%state_type_char(current_state%state_type), &
1956 " for atom", current_state%at_index,
" of kind ", trim(current_state%at_symbol),
":"
1960 CALL assign_mos_to_donor_state(current_state, xas_tdp_env, xas_tdp_control, qs_env)
1961 CALL perform_mulliken_on_donor_state(current_state, qs_env)
1963 current_state_index = current_state_index + 1
1964 NULLIFY (current_state)
1970 IF (output_unit > 0)
THEN
1971 WRITE (output_unit,
"(/,T5,A)") &
1972 "Use LOCALIZE and/or increase N_SEARCH for better results, if so required."
1975 END SUBROUTINE print_checks
1985 SUBROUTINE compute_lenrep_multipole(iatom, xas_tdp_env, xas_tdp_control, qs_env)
1987 INTEGER,
INTENT(IN) :: iatom
1988 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
1989 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
1990 TYPE(qs_environment_type),
POINTER :: qs_env
1993 REAL(
dp),
DIMENSION(3) :: rc
1994 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: work
1995 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
1997 NULLIFY (work, particle_set)
1999 CALL get_qs_env(qs_env, particle_set=particle_set)
2000 rc = particle_set(iatom)%r
2003 IF (xas_tdp_control%dipole_form ==
xas_dip_len)
THEN
2005 CALL dbcsr_set(xas_tdp_env%dipmat(i)%matrix, 0.0_dp)
2006 work(i)%matrix => xas_tdp_env%dipmat(i)%matrix
2010 IF (xas_tdp_control%do_quad)
THEN
2012 CALL dbcsr_set(xas_tdp_env%quadmat(i)%matrix, 0.0_dp)
2013 work(3 + i)%matrix => xas_tdp_env%quadmat(i)%matrix
2016 IF (xas_tdp_control%dipole_form ==
xas_dip_vel) order = -2
2020 CALL rrc_xyz_ao(work, qs_env, rc, order=order, minimum_image=.true.)
2023 END SUBROUTINE compute_lenrep_multipole
2037 SUBROUTINE compute_dipole_fosc(donor_state, xas_tdp_control, xas_tdp_env)
2039 TYPE(donor_state_type),
POINTER :: donor_state
2040 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2041 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2043 CHARACTER(len=*),
PARAMETER :: routinen =
'compute_dipole_fosc'
2045 INTEGER :: handle, iosc, j, nao, ndo_mo, ndo_so, &
2047 LOGICAL :: do_sc, do_sg
2048 REAL(
dp) :: osc_xyz, pref
2049 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: tot_contr
2050 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: dip_block
2051 REAL(
dp),
DIMENSION(:),
POINTER :: lr_evals
2052 REAL(
dp),
DIMENSION(:, :),
POINTER :: osc_str
2053 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
2054 TYPE(cp_fm_struct_type),
POINTER :: col_struct, mat_struct
2055 TYPE(cp_fm_type) :: col_work, mat_work
2056 TYPE(cp_fm_type),
POINTER :: lr_coeffs
2057 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: dipmat
2058 TYPE(mp_para_env_type),
POINTER :: para_env
2060 NULLIFY (dipmat, col_struct, mat_struct, para_env, blacs_env, lr_coeffs)
2061 NULLIFY (lr_evals, osc_str)
2063 CALL timeset(routinen, handle)
2066 do_sc = xas_tdp_control%do_spin_cons
2067 do_sg = xas_tdp_control%do_singlet
2070 lr_evals => donor_state%sc_evals
2071 lr_coeffs => donor_state%sc_coeffs
2072 ELSE IF (do_sg)
THEN
2074 lr_evals => donor_state%sg_evals
2075 lr_coeffs => donor_state%sg_coeffs
2077 cpabort(
"Dipole oscilaltor strength only for singlets and spin-conserving excitations.")
2079 ndo_mo = donor_state%ndo_mo
2080 ndo_so = ndo_mo*nspins
2081 ngs = ndo_so;
IF (xas_tdp_control%do_roks) ngs = ndo_mo
2082 nosc =
SIZE(lr_evals)
2083 ALLOCATE (donor_state%osc_str(nosc, 4))
2084 osc_str => donor_state%osc_str
2086 dipmat => xas_tdp_env%dipmat
2089 CALL cp_fm_get_info(donor_state%gs_coeffs, matrix_struct=col_struct, para_env=para_env, &
2090 context=blacs_env, nrow_global=nao)
2092 nrow_global=ndo_so*nosc, ncol_global=ngs)
2096 ALLOCATE (tot_contr(ndo_mo), dip_block(ndo_so, ngs))
2097 pref = 2.0_dp;
IF (do_sc) pref = 1.0_dp
2105 CALL parallel_gemm(
'T',
'N', ndo_so*nosc, ngs, nao, 1.0_dp, lr_coeffs, col_work, 0.0_dp, mat_work)
2111 CALL cp_fm_get_submatrix(fm=mat_work, target_m=dip_block, start_row=(iosc - 1)*ndo_so + 1, &
2112 start_col=1, n_rows=ndo_so, n_cols=ngs)
2115 ELSE IF (do_sc .AND. xas_tdp_control%do_uks)
THEN
2116 tot_contr(:) =
get_diag(dip_block(1:ndo_mo, 1:ndo_mo))
2117 tot_contr(:) = tot_contr(:) +
get_diag(dip_block(ndo_mo + 1:ndo_so, ndo_mo + 1:ndo_so))
2120 tot_contr(:) =
get_diag(dip_block(1:ndo_mo, :))
2121 tot_contr(:) = tot_contr(:) +
get_diag(dip_block(ndo_mo + 1:ndo_so, :))
2124 osc_xyz = sum(tot_contr)**2
2125 osc_str(iosc, 4) = osc_str(iosc, 4) + osc_xyz
2126 osc_str(iosc, j) = osc_xyz
2133 IF (xas_tdp_control%dipole_form ==
xas_dip_len)
THEN
2134 osc_str(:, j) = pref*2.0_dp/3.0_dp*lr_evals(:)*osc_str(:, j)
2136 osc_str(:, j) = pref*2.0_dp/3.0_dp/lr_evals(:)*osc_str(:, j)
2141 CALL cp_fm_release(mat_work)
2142 CALL cp_fm_release(col_work)
2145 CALL timestop(handle)
2147 END SUBROUTINE compute_dipole_fosc
2157 SUBROUTINE compute_quadrupole_fosc(donor_state, xas_tdp_control, xas_tdp_env)
2159 TYPE(donor_state_type),
POINTER :: donor_state
2160 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2161 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2163 CHARACTER(len=*),
PARAMETER :: routinen =
'compute_quadrupole_fosc'
2165 INTEGER :: handle, iosc, j, nao, ndo_mo, ndo_so, &
2167 LOGICAL :: do_sc, do_sg
2169 REAL(
dp),
ALLOCATABLE,
DIMENSION(:) :: tot_contr, trace
2170 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: quad_block
2171 REAL(
dp),
DIMENSION(:),
POINTER :: lr_evals, osc_str
2172 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
2173 TYPE(cp_fm_struct_type),
POINTER :: col_struct, mat_struct
2174 TYPE(cp_fm_type) :: col_work, mat_work
2175 TYPE(cp_fm_type),
POINTER :: lr_coeffs
2176 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: quadmat
2177 TYPE(mp_para_env_type),
POINTER :: para_env
2179 NULLIFY (lr_evals, osc_str, lr_coeffs, col_struct, mat_struct, para_env)
2182 CALL timeset(routinen, handle)
2185 do_sc = xas_tdp_control%do_spin_cons
2186 do_sg = xas_tdp_control%do_singlet
2189 lr_evals => donor_state%sc_evals
2190 lr_coeffs => donor_state%sc_coeffs
2191 ELSE IF (do_sg)
THEN
2193 lr_evals => donor_state%sg_evals
2194 lr_coeffs => donor_state%sg_coeffs
2196 cpabort(
"Quadrupole oscillator strengths only for singlet and spin-conserving excitations")
2198 ndo_mo = donor_state%ndo_mo
2199 ndo_so = ndo_mo*nspins
2200 ngs = ndo_so;
IF (xas_tdp_control%do_roks) ngs = ndo_mo
2201 nosc =
SIZE(lr_evals)
2202 ALLOCATE (donor_state%quad_osc_str(nosc))
2203 osc_str => donor_state%quad_osc_str
2205 quadmat => xas_tdp_env%quadmat
2208 CALL cp_fm_get_info(donor_state%gs_coeffs, matrix_struct=col_struct, para_env=para_env, &
2209 context=blacs_env, nrow_global=nao)
2211 nrow_global=ndo_so*nosc, ncol_global=ngs)
2215 ALLOCATE (quad_block(ndo_so, ngs), tot_contr(ndo_mo))
2216 pref = 2.0_dp;
IF (do_sc) pref = 1.0_dp
2217 ALLOCATE (trace(nosc))
2226 CALL parallel_gemm(
'T',
'N', ndo_so*nosc, ngs, nao, 1.0_dp, lr_coeffs, col_work, 0.0_dp, mat_work)
2232 CALL cp_fm_get_submatrix(fm=mat_work, target_m=quad_block, start_row=(iosc - 1)*ndo_so + 1, &
2233 start_col=1, n_rows=ndo_so, n_cols=ngs)
2236 tot_contr(:) =
get_diag(quad_block)
2237 ELSE IF (do_sc .AND. xas_tdp_control%do_uks)
THEN
2238 tot_contr(:) =
get_diag(quad_block(1:ndo_mo, 1:ndo_mo))
2239 tot_contr(:) = tot_contr(:) +
get_diag(quad_block(ndo_mo + 1:ndo_so, ndo_mo + 1:ndo_so))
2242 tot_contr(:) =
get_diag(quad_block(1:ndo_mo, :))
2243 tot_contr(:) = tot_contr(:) +
get_diag(quad_block(ndo_mo + 1:ndo_so, :))
2247 IF (j == 1 .OR. j == 4 .OR. j == 6)
THEN
2248 osc_str(iosc) = osc_str(iosc) + sum(tot_contr)**2
2249 trace(iosc) = trace(iosc) + sum(tot_contr)
2253 osc_str(iosc) = osc_str(iosc) + 2.0_dp*sum(tot_contr)**2
2260 osc_str(:) = pref*1._dp/20._dp*
a_fine**2*lr_evals(:)**3*(osc_str(:) - 1._dp/3._dp*trace(:)**2)
2263 CALL cp_fm_release(mat_work)
2264 CALL cp_fm_release(col_work)
2267 CALL timestop(handle)
2269 END SUBROUTINE compute_quadrupole_fosc
2278 SUBROUTINE write_mos_to_ex_atoms_association(xas_tdp_env, xas_tdp_control, qs_env)
2280 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2281 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2282 TYPE(qs_environment_type),
POINTER :: qs_env
2284 CHARACTER(LEN=default_string_length) :: kind_name
2285 INTEGER :: at_index, imo, ispin, nmo, nspins, &
2286 output_unit, tmp_index
2287 INTEGER,
DIMENSION(3) :: perd_init
2288 INTEGER,
DIMENSION(:),
POINTER :: ex_atom_indices
2289 INTEGER,
DIMENSION(:, :, :),
POINTER :: mos_of_ex_atoms
2290 REAL(
dp) :: dist, mo_spread
2291 REAL(
dp),
DIMENSION(3) :: at_pos, r_ac, wfn_center
2292 TYPE(cell_type),
POINTER :: cell
2293 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
2295 NULLIFY (cell, particle_set, mos_of_ex_atoms, ex_atom_indices)
2299 IF (output_unit > 0)
THEN
2300 WRITE (unit=output_unit, fmt=
"(/,T3,A,/,T3,A,/,T3,A)") &
2301 " Associated Associated Distance to MO spread (Ang^2)", &
2302 "Spin MO index atom index atom kind MO center (Ang) -w_i ln(|z_ij|^2)", &
2303 "---------------------------------------------------------------------------------"
2307 nspins = 1;
IF (xas_tdp_control%do_uks) nspins = 2
2308 mos_of_ex_atoms => xas_tdp_env%mos_of_ex_atoms
2309 ex_atom_indices => xas_tdp_env%ex_atom_indices
2310 nmo = xas_tdp_control%n_search
2311 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, cell=cell)
2314 perd_init = cell%perd
2319 DO ispin = 1, nspins
2322 IF (any(mos_of_ex_atoms(imo, :, ispin) == 1))
THEN
2323 tmp_index = maxloc(mos_of_ex_atoms(imo, :, ispin), 1)
2324 at_index = ex_atom_indices(tmp_index)
2325 kind_name = particle_set(at_index)%atomic_kind%name
2327 at_pos = particle_set(at_index)%r
2328 wfn_center = xas_tdp_env%qs_loc_env%localized_wfn_control%centers_set(ispin)%array(1:3, imo)
2329 r_ac =
pbc(at_pos, wfn_center, cell)
2334 mo_spread = xas_tdp_env%qs_loc_env%localized_wfn_control%centers_set(ispin)%array(4, imo)
2337 IF (output_unit > 0)
THEN
2338 WRITE (unit=output_unit, fmt=
"(T3,I4,I10,I14,A14,ES19.3,ES20.3)") &
2339 ispin, imo, at_index, trim(kind_name), dist, mo_spread
2346 IF (output_unit > 0)
THEN
2347 WRITE (unit=output_unit, fmt=
"(T3,A,/)") &
2348 "---------------------------------------------------------------------------------"
2352 cell%perd = perd_init
2354 END SUBROUTINE write_mos_to_ex_atoms_association
2365 SUBROUTINE perform_mulliken_on_donor_state(donor_state, qs_env)
2366 TYPE(donor_state_type),
POINTER :: donor_state
2367 TYPE(qs_environment_type),
POINTER :: qs_env
2369 INTEGER :: at_index, i, ispin, nao, natom, ndo_mo, &
2370 ndo_so, nsgf, nspins, output_unit
2371 INTEGER,
DIMENSION(:),
POINTER :: first_sgf, last_sgf
2372 INTEGER,
DIMENSION(:, :),
POINTER :: mo_indices
2373 REAL(
dp),
ALLOCATABLE,
DIMENSION(:, :) :: mul_pop, pop_mat
2374 REAL(
dp),
DIMENSION(:, :),
POINTER :: work_array
2375 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
2376 TYPE(cp_fm_struct_type),
POINTER :: col_vect_struct
2377 TYPE(cp_fm_type) :: work_vect
2378 TYPE(cp_fm_type),
POINTER :: gs_coeffs
2379 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_s
2380 TYPE(mp_para_env_type),
POINTER :: para_env
2381 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
2382 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2384 NULLIFY (mo_indices, qs_kind_set, particle_set, first_sgf, work_array)
2385 NULLIFY (matrix_s, para_env, blacs_env, col_vect_struct, last_sgf)
2388 at_index = donor_state%at_index
2389 mo_indices => donor_state%mo_indices
2390 ndo_mo = donor_state%ndo_mo
2391 gs_coeffs => donor_state%gs_coeffs
2393 nspins = 1;
IF (
SIZE(mo_indices, 2) == 2) nspins = 2
2394 ndo_so = ndo_mo*nspins
2395 ALLOCATE (mul_pop(ndo_mo, nspins))
2398 CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, qs_kind_set=qs_kind_set, &
2399 para_env=para_env, blacs_env=blacs_env, matrix_s=matrix_s)
2400 CALL cp_fm_get_info(gs_coeffs, nrow_global=nao, matrix_struct=col_vect_struct)
2402 natom =
SIZE(particle_set, 1)
2403 ALLOCATE (first_sgf(natom))
2404 ALLOCATE (last_sgf(natom))
2406 CALL get_particle_set(particle_set, qs_kind_set, first_sgf=first_sgf, last_sgf=last_sgf)
2407 nsgf = last_sgf(at_index) - first_sgf(at_index) + 1
2415 ALLOCATE (work_array(nsgf, ndo_so))
2416 ALLOCATE (pop_mat(ndo_so, ndo_so))
2418 CALL cp_fm_get_submatrix(fm=work_vect, target_m=work_array, start_row=first_sgf(at_index), &
2419 start_col=1, n_rows=nsgf, n_cols=ndo_so, transpose=.false.)
2421 CALL dgemm(
'T',
'N', ndo_so, ndo_so, nsgf, 1.0_dp, donor_state%contract_coeffs, nsgf, &
2422 work_array, nsgf, 0.0_dp, pop_mat, ndo_so)
2425 DO ispin = 1, nspins
2427 mul_pop(i, ispin) = pop_mat((ispin - 1)*ndo_mo + i, (ispin - 1)*ndo_mo + i)
2432 IF (output_unit > 0)
THEN
2433 WRITE (unit=output_unit, fmt=
"(T5,A,/,T5,A)") &
2434 "Mulliken population analysis retricted to the associated MO(s) yields: ", &
2435 " Spin MO index charge"
2436 DO ispin = 1, nspins
2438 WRITE (unit=output_unit, fmt=
"(T51,I4,I10,F11.3)") &
2439 ispin, mo_indices(i, ispin), mul_pop(i, ispin)
2445 DEALLOCATE (first_sgf, last_sgf, work_array)
2446 CALL cp_fm_release(work_vect)
2448 END SUBROUTINE perform_mulliken_on_donor_state
2458 SUBROUTINE xas_tdp_post(ex_type, donor_state, xas_tdp_env, xas_tdp_section, qs_env)
2460 INTEGER,
INTENT(IN) :: ex_type
2461 TYPE(donor_state_type),
POINTER :: donor_state
2462 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2463 TYPE(section_vals_type),
POINTER :: xas_tdp_section
2464 TYPE(qs_environment_type),
POINTER :: qs_env
2466 CHARACTER(len=*),
PARAMETER :: routinen =
'xas_tdp_post'
2468 CHARACTER(len=default_string_length) :: domo, domon, excite, pos, xas_mittle
2469 INTEGER :: ex_state_idx, handle, ic, ido_mo, imo, irep, ispin, n_dependent, n_rep, nao, &
2470 ncubes, ndo_mo, ndo_so, nlumo, nmo, nspins, output_unit
2471 INTEGER,
DIMENSION(:),
POINTER :: bounds,
list, state_list
2472 LOGICAL :: append_cube, do_cubes, do_pdos, &
2474 REAL(
dp),
DIMENSION(:),
POINTER :: lr_evals
2475 REAL(
dp),
DIMENSION(:, :),
POINTER :: centers
2476 TYPE(atomic_kind_type),
DIMENSION(:),
POINTER :: atomic_kind_set
2477 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
2478 TYPE(cp_fm_struct_type),
POINTER :: fm_struct, mo_struct
2479 TYPE(cp_fm_type) :: mo_coeff, work_fm
2480 TYPE(cp_fm_type),
POINTER :: lr_coeffs
2481 TYPE(cp_logger_type),
POINTER :: logger
2482 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_s
2483 TYPE(mo_set_type),
DIMENSION(:),
POINTER :: mos
2484 TYPE(mo_set_type),
POINTER :: mo_set
2485 TYPE(mp_para_env_type),
POINTER :: para_env
2486 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
2487 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2488 TYPE(section_vals_type),
POINTER :: print_key
2490 NULLIFY (atomic_kind_set, particle_set, qs_kind_set, mo_set, lr_evals, lr_coeffs)
2491 NULLIFY (mo_struct, para_env, blacs_env, fm_struct, matrix_s, print_key, logger)
2492 NULLIFY (bounds, state_list,
list, mos)
2496 do_pdos = .false.; do_cubes = .false.; do_wfn_restart = .false.
2499 "PRINT%PDOS"),
cp_p_file)) do_pdos = .true.
2502 "PRINT%CUBES"),
cp_p_file)) do_cubes = .true.
2505 "PRINT%RESTART_WFN"),
cp_p_file)) do_wfn_restart = .true.
2507 IF (.NOT. (do_pdos .OR. do_cubes .OR. do_wfn_restart))
RETURN
2509 CALL timeset(routinen, handle)
2512 CALL get_qs_env(qs_env, atomic_kind_set=atomic_kind_set, particle_set=particle_set, &
2513 qs_kind_set=qs_kind_set, para_env=para_env, blacs_env=blacs_env, &
2514 matrix_s=matrix_s, mos=mos)
2516 SELECT CASE (ex_type)
2518 lr_evals => donor_state%sc_evals
2519 lr_coeffs => donor_state%sc_coeffs
2523 lr_evals => donor_state%sf_evals
2524 lr_coeffs => donor_state%sf_coeffs
2528 lr_evals => donor_state%sg_evals
2529 lr_coeffs => donor_state%sg_coeffs
2533 lr_evals => donor_state%tp_evals
2534 lr_coeffs => donor_state%tp_coeffs
2539 SELECT CASE (donor_state%state_type)
2548 ndo_mo = donor_state%ndo_mo
2549 ndo_so = ndo_mo*nspins
2550 nmo =
SIZE(lr_evals)
2551 CALL dbcsr_get_info(matrix_s(1)%matrix, nfullrows_total=nao)
2554 nrow_global=nao, ncol_global=nmo)
2558 IF (do_wfn_restart)
THEN
2560 TYPE(mo_set_type),
DIMENSION(2) :: restart_mos
2561 IF (.NOT. (nspins == 1 .AND. donor_state%state_type ==
xas_1s_type))
THEN
2562 cpabort(
"RESTART.wfn file only available for RKS K-edge XAS spectroscopy")
2565 CALL section_vals_val_get(xas_tdp_section,
"PRINT%RESTART_WFN%EXCITED_STATE_INDEX", n_rep_val=n_rep)
2569 i_rep_val=irep, i_val=ex_state_idx)
2570 cpassert(ex_state_idx <=
SIZE(lr_evals))
2575 IF (
SIZE(mos) == 1) &
2576 restart_mos(ispin)%occupation_numbers = mos(1)%occupation_numbers/2
2579 CALL cp_fm_to_fm_submat(msource=lr_coeffs, mtarget=restart_mos(1)%mo_coeff, nrow=nao, &
2580 ncol=1, s_firstrow=1, s_firstcol=ex_state_idx, t_firstrow=1, &
2581 t_firstcol=donor_state%mo_indices(1, 1))
2583 xas_mittle =
'xasat'//trim(adjustl(cp_to_string(donor_state%at_index)))//
'_'//trim(domo)// &
2584 '_'//trim(excite)//
'_idx'//trim(adjustl(cp_to_string(ex_state_idx)))
2586 extension=
".wfn", file_status=
"REPLACE", &
2587 file_action=
"WRITE", file_form=
"UNFORMATTED", &
2588 middle_name=xas_mittle)
2591 qs_kind_set=qs_kind_set, ires=output_unit)
2606 IF (.NOT.
ASSOCIATED(xas_tdp_env%matrix_shalf) .AND. do_pdos)
THEN
2608 nrow_global=nao, ncol_global=nao)
2609 ALLOCATE (xas_tdp_env%matrix_shalf)
2614 CALL cp_fm_power(xas_tdp_env%matrix_shalf, work_fm, 0.5_dp, epsilon(0.0_dp), n_dependent)
2616 CALL cp_fm_release(work_fm)
2622 IF (output_unit > 0)
THEN
2623 WRITE (unit=output_unit, fmt=
"(/,T5,A,/,T5,A,/,T5,A)") &
2624 "Computing the PDOS of linear-response orbitals for spectral features analysis", &
2625 "Note: using standard PDOS routines => ignore mentions of KS states and MO ", &
2626 " occupation numbers. Eigenvalues in *.pdos files are excitations energies."
2631 IF (nlumo .NE. 0)
THEN
2632 cpwarn(
"NLUMO is irrelevant for XAS_TDP PDOS. It was overwritten to 0.")
2643 ncubes = bounds(2) - bounds(1) + 1
2644 IF (ncubes > 0)
THEN
2645 ALLOCATE (state_list(ncubes))
2647 state_list(ic) = bounds(1) + ic - 1
2651 IF (.NOT.
ASSOCIATED(state_list))
THEN
2658 IF (
ASSOCIATED(
list))
THEN
2659 CALL reallocate(state_list, 1, ncubes +
SIZE(
list))
2660 DO ic = 1,
SIZE(
list)
2661 state_list(ncubes + ic) =
list(ic)
2663 ncubes = ncubes +
SIZE(
list)
2668 IF (.NOT.
ASSOCIATED(state_list))
THEN
2670 ALLOCATE (state_list(1))
2676 IF (append_cube) pos =
"APPEND"
2678 ALLOCATE (centers(6, ncubes))
2684 DO ido_mo = 1, ndo_mo
2685 DO ispin = 1, nspins
2689 CALL allocate_mo_set(mo_set, nao=nao, nmo=nmo, nelectron=nmo, n_el_f=real(nmo,
dp), &
2690 maxocc=1.0_dp, flexible_electron_count=0.0_dp)
2691 CALL init_mo_set(mo_set, fm_ref=mo_coeff, name=
"PDOS XAS_TDP MOs")
2692 mo_set%eigenvalues(:) = lr_evals(:)
2695 IF (nspins == 1 .AND. ndo_mo == 1)
THEN
2696 CALL cp_fm_to_fm(lr_coeffs, mo_set%mo_coeff)
2700 nrow=nao, ncol=1, s_firstrow=1, &
2701 s_firstcol=(imo - 1)*ndo_so + (ispin - 1)*ndo_mo + ido_mo, &
2702 t_firstrow=1, t_firstcol=imo)
2708 IF (donor_state%state_type ==
xas_2p_type) domon = trim(domo)//trim(adjustl(cp_to_string(ido_mo)))
2709 xas_mittle =
'xasat'//trim(adjustl(cp_to_string(donor_state%at_index)))//
'_'// &
2710 trim(domon)//
'_'//trim(excite)
2714 qs_env, xas_tdp_section, ispin, xas_mittle, &
2715 external_matrix_shalf=xas_tdp_env%matrix_shalf)
2719 CALL qs_print_cubes(qs_env, mo_set%mo_coeff, ncubes, state_list, centers, &
2720 print_key=print_key, root=xas_mittle, ispin=ispin, &
2732 CALL cp_fm_release(mo_coeff)
2734 IF (do_cubes)
DEALLOCATE (centers, state_list)
2736 CALL timestop(handle)
2738 END SUBROUTINE xas_tdp_post
2748 SUBROUTINE make_lumo_guess(xas_tdp_env, xas_tdp_control, qs_env)
2750 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2751 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2752 TYPE(qs_environment_type),
POINTER :: qs_env
2754 CHARACTER(len=*),
PARAMETER :: routinen =
'make_lumo_guess'
2756 INTEGER :: handle, ispin, nao, nelec_spin(2), &
2757 nlumo(2), nocc(2), nspins
2759 REAL(dp),
ALLOCATABLE,
DIMENSION(:) :: evals
2760 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
2761 TYPE(cp_fm_struct_type),
POINTER :: fm_struct, lumo_struct
2762 TYPE(cp_fm_type) :: amatrix, bmatrix, evecs, work_fm
2763 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_ks, matrix_s
2764 TYPE(mp_para_env_type),
POINTER :: para_env
2766 NULLIFY (matrix_ks, matrix_s, para_env, blacs_env)
2767 NULLIFY (lumo_struct, fm_struct)
2769 CALL timeset(routinen, handle)
2771 do_os = xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks
2772 nspins = 1;
IF (do_os) nspins = 2
2773 ALLOCATE (xas_tdp_env%lumo_evecs(nspins))
2774 ALLOCATE (xas_tdp_env%lumo_evals(nspins))
2775 CALL get_qs_env(qs_env, matrix_ks=matrix_ks, matrix_s=matrix_s, nelectron_spin=nelec_spin, &
2776 para_env=para_env, blacs_env=blacs_env)
2777 CALL dbcsr_get_info(matrix_s(1)%matrix, nfullrows_total=nao)
2780 nlumo = nao - nelec_spin
2783 nlumo = nao - nelec_spin(1)/2
2784 nocc = nelec_spin(1)/2
2787 ALLOCATE (xas_tdp_env%ot_prec(nspins))
2789 DO ispin = 1, nspins
2792 CALL cp_fm_struct_create(fm_struct, para_env=para_env, context=blacs_env, &
2793 nrow_global=nao, ncol_global=nao)
2794 CALL cp_fm_create(amatrix, fm_struct)
2795 CALL cp_fm_create(bmatrix, fm_struct)
2796 CALL cp_fm_create(evecs, fm_struct)
2797 CALL cp_fm_create(work_fm, fm_struct)
2798 ALLOCATE (evals(nao))
2799 ALLOCATE (xas_tdp_env%lumo_evals(ispin)%array(nlumo(ispin)))
2801 CALL copy_dbcsr_to_fm(matrix_ks(ispin)%matrix, amatrix)
2802 CALL copy_dbcsr_to_fm(matrix_s(1)%matrix, bmatrix)
2805 CALL cp_fm_geeig(amatrix, bmatrix, evecs, evals, work_fm)
2808 CALL cp_fm_struct_create(lumo_struct, para_env=para_env, context=blacs_env, &
2809 nrow_global=nao, ncol_global=nlumo(ispin))
2810 CALL cp_fm_create(xas_tdp_env%lumo_evecs(ispin), lumo_struct)
2812 CALL cp_fm_to_fm_submat(evecs, xas_tdp_env%lumo_evecs(ispin), nrow=nao, &
2813 ncol=nlumo(ispin), s_firstrow=1, s_firstcol=nocc(ispin) + 1, &
2814 t_firstrow=1, t_firstcol=1)
2816 xas_tdp_env%lumo_evals(ispin)%array(1:nlumo(ispin)) = evals(nocc(ispin) + 1:nao)
2818 CALL build_ot_spin_prec(evecs, evals, ispin, xas_tdp_env, xas_tdp_control, qs_env)
2821 CALL cp_fm_release(amatrix)
2822 CALL cp_fm_release(bmatrix)
2823 CALL cp_fm_release(evecs)
2824 CALL cp_fm_release(work_fm)
2825 CALL cp_fm_struct_release(fm_struct)
2826 CALL cp_fm_struct_release(lumo_struct)
2830 CALL timestop(handle)
2832 END SUBROUTINE make_lumo_guess
2845 SUBROUTINE build_ot_spin_prec(evecs, evals, ispin, xas_tdp_env, xas_tdp_control, qs_env)
2847 TYPE(cp_fm_type),
INTENT(IN) :: evecs
2848 REAL(dp),
DIMENSION(:) :: evals
2850 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2851 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2852 TYPE(qs_environment_type),
POINTER :: qs_env
2854 CHARACTER(len=*),
PARAMETER :: routinen =
'build_ot_spin_prec'
2856 INTEGER :: handle, nao, nelec_spin(2), nguess, &
2860 REAL(dp),
ALLOCATABLE,
DIMENSION(:) :: scaling
2861 TYPE(cp_fm_struct_type),
POINTER :: fm_struct
2862 TYPE(cp_fm_type) :: fm_prec, work_fm
2863 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_s
2864 TYPE(mp_para_env_type),
POINTER :: para_env
2866 NULLIFY (fm_struct, para_env, matrix_s)
2868 CALL timeset(routinen, handle)
2870 do_os = xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks
2871 CALL get_qs_env(qs_env, para_env=para_env, nelectron_spin=nelec_spin, matrix_s=matrix_s)
2872 CALL cp_fm_get_info(evecs, nrow_global=nao, matrix_struct=fm_struct)
2873 CALL cp_fm_create(fm_prec, fm_struct)
2874 ALLOCATE (scaling(nao))
2875 nocc = nelec_spin(1)/2
2878 nocc = nelec_spin(ispin)
2884 IF (xas_tdp_control%n_excited > 0 .AND. xas_tdp_control%n_excited < nguess)
THEN
2885 nguess = xas_tdp_control%n_excited/nspins
2886 ELSE IF (xas_tdp_control%e_range > 0.0_dp)
THEN
2887 nguess = count(evals(nocc + 1:nao) - evals(nocc + 1) .LE. xas_tdp_control%e_range)
2891 scaling(nocc + 1:nocc + nguess) = 100.0_dp
2893 shift = evals(nocc + 1) - 0.01_dp
2894 scaling(nocc + nguess:nao) = 1.0_dp/(evals(nocc + nguess:nao) - shift)
2896 scaling(1:nocc) = 1.0_dp
2899 CALL cp_fm_create(work_fm, fm_struct)
2901 CALL cp_fm_copy_general(evecs, work_fm, para_env)
2902 CALL cp_fm_column_scale(work_fm, scaling)
2904 CALL parallel_gemm(
'N',
'T', nao, nao, nao, 1.0_dp, work_fm, evecs, 0.0_dp, fm_prec)
2907 ALLOCATE (xas_tdp_env%ot_prec(ispin)%matrix)
2908 CALL dbcsr_create(xas_tdp_env%ot_prec(ispin)%matrix, template=matrix_s(1)%matrix, name=
"OT_PREC")
2909 CALL copy_fm_to_dbcsr(fm_prec, xas_tdp_env%ot_prec(ispin)%matrix)
2910 CALL dbcsr_filter(xas_tdp_env%ot_prec(ispin)%matrix, xas_tdp_control%eps_filter)
2912 CALL cp_fm_release(work_fm)
2913 CALL cp_fm_release(fm_prec)
2915 CALL timestop(handle)
2917 END SUBROUTINE build_ot_spin_prec
2926 SUBROUTINE print_xps(donor_state, xas_tdp_env, xas_tdp_control, qs_env)
2928 TYPE(donor_state_type),
POINTER :: donor_state
2929 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2930 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2931 TYPE(qs_environment_type),
POINTER :: qs_env
2933 INTEGER :: ido_mo, ispin, nspins, output_unit
2934 REAL(dp),
ALLOCATABLE,
DIMENSION(:, :) :: ips, soc_shifts
2936 output_unit = cp_logger_get_default_io_unit()
2938 nspins = 1;
IF (xas_tdp_control%do_uks .OR. xas_tdp_control%do_roks) nspins = 2
2940 ALLOCATE (ips(
SIZE(donor_state%gw2x_evals, 1),
SIZE(donor_state%gw2x_evals, 2)))
2941 ips(:, :) = donor_state%gw2x_evals(:, :)
2944 IF (.NOT. xas_tdp_control%is_periodic)
THEN
2947 IF (donor_state%ndo_mo > 1)
THEN
2948 CALL get_soc_splitting(soc_shifts, donor_state, xas_tdp_env, xas_tdp_control, qs_env)
2949 ips(:, :) = ips(:, :) + soc_shifts
2951 IF (output_unit > 0)
THEN
2952 WRITE (output_unit, fmt=
"(/,T5,A,F23.6)") &
2953 "Ionization potentials for XPS (GW2X + SOC): ", -ips(1, 1)*evolt
2955 DO ispin = 1, nspins
2956 DO ido_mo = 1, donor_state%ndo_mo
2958 IF (ispin == 1 .AND. ido_mo == 1) cycle
2960 WRITE (output_unit, fmt=
"(T5,A,F23.6)") &
2961 " ", -ips(ido_mo, ispin)*evolt
2970 IF (output_unit > 0)
THEN
2971 WRITE (output_unit, fmt=
"(/,T5,A,F29.6)") &
2972 "Ionization potentials for XPS (GW2X): ", -ips(1, 1)*evolt
2974 IF (nspins == 2)
THEN
2975 WRITE (output_unit, fmt=
"(T5,A,F29.6)") &
2976 " ", -ips(1, 2)*evolt
2983 END SUBROUTINE print_xps
2992 SUBROUTINE print_xas_tdp_to_file(donor_state, xas_tdp_env, xas_tdp_control, xas_tdp_section)
2994 TYPE(donor_state_type),
POINTER :: donor_state
2995 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
2996 TYPE(xas_tdp_control_type),
POINTER :: xas_tdp_control
2997 TYPE(section_vals_type),
POINTER :: xas_tdp_section
2999 INTEGER :: i, output_unit, xas_tdp_unit
3000 TYPE(cp_logger_type),
POINTER :: logger
3003 logger => cp_get_default_logger()
3005 xas_tdp_unit = cp_print_key_unit_nr(logger, xas_tdp_section,
"PRINT%SPECTRUM", &
3006 extension=
".spectrum", file_position=
"APPEND", &
3007 file_action=
"WRITE", file_form=
"FORMATTED")
3009 output_unit = cp_logger_get_default_io_unit()
3011 IF (output_unit > 0)
THEN
3012 WRITE (output_unit, fmt=
"(/,T5,A,/)") &
3013 "Calculations done: "
3016 IF (xas_tdp_control%do_spin_cons)
THEN
3017 IF (xas_tdp_unit > 0)
THEN
3020 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3021 "==================================================================================", &
3022 "XAS TDP open-shell spin-conserving (no SOC) excitations for DONOR STATE: ", &
3023 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3024 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3025 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3026 "=================================================================================="
3030 IF (xas_tdp_control%do_quad)
THEN
3031 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3032 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3033 DO i = 1,
SIZE(donor_state%sc_evals)
3034 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3035 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4), &
3036 donor_state%quad_osc_str(i)
3038 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3039 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3040 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3041 DO i = 1,
SIZE(donor_state%sc_evals)
3042 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3043 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4), &
3044 donor_state%osc_str(i, 1), donor_state%osc_str(i, 2), donor_state%osc_str(i, 3)
3047 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3048 " Index Excitation energy (eV) fosc dipole (a.u.)"
3049 DO i = 1,
SIZE(donor_state%sc_evals)
3050 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3051 i, donor_state%sc_evals(i)*evolt, donor_state%osc_str(i, 4)
3055 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3058 IF (output_unit > 0)
THEN
3059 WRITE (output_unit, fmt=
"(T5,A,F17.6)") &
3060 "First spin-conserving XAS excitation energy (eV): ", donor_state%sc_evals(1)*evolt
3065 IF (xas_tdp_control%do_spin_flip)
THEN
3066 IF (xas_tdp_unit > 0)
THEN
3069 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3070 "==================================================================================", &
3071 "XAS TDP open-shell spin-flip (no SOC) excitations for DONOR STATE: ", &
3072 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3073 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3074 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3075 "=================================================================================="
3079 IF (xas_tdp_control%do_quad)
THEN
3080 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3081 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3082 DO i = 1,
SIZE(donor_state%sf_evals)
3083 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3084 i, donor_state%sf_evals(i)*evolt, 0.0_dp, 0.0_dp
3086 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3087 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3088 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3089 DO i = 1,
SIZE(donor_state%sf_evals)
3090 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3091 i, donor_state%sf_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp
3094 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3095 " Index Excitation energy (eV) fosc dipole (a.u.)"
3096 DO i = 1,
SIZE(donor_state%sf_evals)
3097 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3098 i, donor_state%sf_evals(i)*evolt, 0.0_dp
3102 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3105 IF (output_unit > 0)
THEN
3106 WRITE (output_unit, fmt=
"(T5,A,F23.6)") &
3107 "First spin-flip XAS excitation energy (eV): ", donor_state%sf_evals(1)*evolt
3111 IF (xas_tdp_control%do_singlet)
THEN
3112 IF (xas_tdp_unit > 0)
THEN
3115 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3116 "==================================================================================", &
3117 "XAS TDP singlet excitations (no SOC) for DONOR STATE: ", &
3118 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3119 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3120 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3121 "=================================================================================="
3125 IF (xas_tdp_control%do_quad)
THEN
3126 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3127 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3128 DO i = 1,
SIZE(donor_state%sg_evals)
3129 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3130 i, donor_state%sg_evals(i)*evolt, donor_state%osc_str(i, 4), &
3131 donor_state%quad_osc_str(i)
3133 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3134 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3135 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3136 DO i = 1,
SIZE(donor_state%sg_evals)
3137 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3138 i, donor_state%sg_evals(i)*evolt, donor_state%osc_str(i, 4), &
3139 donor_state%osc_str(i, 1), donor_state%osc_str(i, 2), donor_state%osc_str(i, 3)
3142 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3143 " Index Excitation energy (eV) fosc dipole (a.u.)"
3144 DO i = 1,
SIZE(donor_state%sg_evals)
3145 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3146 i, donor_state%sg_evals(i)*evolt, donor_state%osc_str(i, 4)
3150 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3153 IF (output_unit > 0)
THEN
3154 WRITE (output_unit, fmt=
"(T5,A,F25.6)") &
3155 "First singlet XAS excitation energy (eV): ", donor_state%sg_evals(1)*evolt
3159 IF (xas_tdp_control%do_triplet)
THEN
3160 IF (xas_tdp_unit > 0)
THEN
3163 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3164 "==================================================================================", &
3165 "XAS TDP triplet excitations (no SOC) for DONOR STATE: ", &
3166 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3167 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3168 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3169 "=================================================================================="
3173 IF (xas_tdp_control%do_quad)
THEN
3174 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3175 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3176 DO i = 1,
SIZE(donor_state%tp_evals)
3177 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3178 i, donor_state%tp_evals(i)*evolt, 0.0_dp, 0.0_dp
3180 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3181 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3182 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3183 DO i = 1,
SIZE(donor_state%tp_evals)
3184 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3185 i, donor_state%tp_evals(i)*evolt, 0.0_dp, 0.0_dp, 0.0_dp, 0.0_dp
3188 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3189 " Index Excitation energy (eV) fosc dipole (a.u.)"
3190 DO i = 1,
SIZE(donor_state%tp_evals)
3191 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3192 i, donor_state%tp_evals(i)*evolt, 0.0_dp
3196 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3199 IF (output_unit > 0)
THEN
3200 WRITE (output_unit, fmt=
"(T5,A,F25.6)") &
3201 "First triplet XAS excitation energy (eV): ", donor_state%tp_evals(1)*evolt
3205 IF (xas_tdp_control%do_soc .AND. donor_state%state_type == xas_2p_type)
THEN
3206 IF (xas_tdp_unit > 0)
THEN
3209 WRITE (xas_tdp_unit, fmt=
"(A,/,A,A,A/,A,I5,A,I5,A,A,/,A)") &
3210 "==================================================================================", &
3211 "XAS TDP excitations after spin-orbit coupling for DONOR STATE: ", &
3212 xas_tdp_env%state_type_char(donor_state%state_type),
",", &
3213 "from EXCITED ATOM: ", donor_state%at_index,
", of KIND (index/symbol): ", &
3214 donor_state%kind_index,
"/", trim(donor_state%at_symbol), &
3215 "=================================================================================="
3218 IF (xas_tdp_control%do_quad)
THEN
3219 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3220 " Index Excitation energy (eV) fosc dipole (a.u.) fosc quadrupole (a.u.)"
3221 DO i = 1,
SIZE(donor_state%soc_evals)
3222 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F25.6)") &
3223 i, donor_state%soc_evals(i)*evolt, donor_state%soc_osc_str(i, 4), &
3224 donor_state%soc_quad_osc_str(i)
3226 ELSE IF (xas_tdp_control%xyz_dip)
THEN
3227 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3228 " Index Excitation energy (eV) fosc dipole (a.u.) x-component y-component z-component"
3229 DO i = 1,
SIZE(donor_state%soc_evals)
3230 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6,F14.6,F14.6,F14.6)") &
3231 i, donor_state%soc_evals(i)*evolt, donor_state%soc_osc_str(i, 4), &
3232 donor_state%soc_osc_str(i, 1), donor_state%soc_osc_str(i, 2), donor_state%soc_osc_str(i, 3)
3235 WRITE (xas_tdp_unit, fmt=
"(T3,A)") &
3236 " Index Excitation energy (eV) fosc dipole (a.u.)"
3237 DO i = 1,
SIZE(donor_state%soc_evals)
3238 WRITE (xas_tdp_unit, fmt=
"(T3,I6,F27.6,F22.6)") &
3239 i, donor_state%soc_evals(i)*evolt, donor_state%soc_osc_str(i, 4)
3243 WRITE (xas_tdp_unit, fmt=
"(A,/)")
" "
3246 IF (output_unit > 0)
THEN
3247 WRITE (output_unit, fmt=
"(T5,A,F29.6)") &
3248 "First SOC XAS excitation energy (eV): ", donor_state%soc_evals(1)*evolt
3252 CALL cp_print_key_finished_output(xas_tdp_unit, logger, xas_tdp_section,
"PRINT%SPECTRUM")
3254 END SUBROUTINE print_xas_tdp_to_file
3264 SUBROUTINE write_donor_state_restart(ex_type, donor_state, xas_tdp_section, qs_env)
3266 INTEGER,
INTENT(IN) :: ex_type
3267 TYPE(donor_state_type),
POINTER :: donor_state
3268 TYPE(section_vals_type),
POINTER :: xas_tdp_section
3269 TYPE(qs_environment_type),
POINTER :: qs_env
3271 CHARACTER(len=*),
PARAMETER :: routinen =
'write_donor_state_restart'
3273 CHARACTER(len=default_path_length) :: filename
3274 CHARACTER(len=default_string_length) :: domo, excite, my_middle
3275 INTEGER :: ex_atom, handle, ispin, nao, ndo_mo, &
3276 nex, nspins, output_unit, rst_unit, &
3278 INTEGER,
DIMENSION(:, :),
POINTER :: mo_indices
3280 REAL(dp),
DIMENSION(:),
POINTER :: lr_evals
3281 TYPE(cp_fm_type),
POINTER :: lr_coeffs
3282 TYPE(cp_logger_type),
POINTER :: logger
3283 TYPE(mo_set_type),
DIMENSION(:),
POINTER :: mos
3284 TYPE(section_vals_type),
POINTER :: print_key
3286 NULLIFY (logger, lr_coeffs, lr_evals, print_key, mos)
3289 logger => cp_get_default_logger()
3291 IF (btest(cp_print_key_should_output(logger%iter_info, xas_tdp_section, &
3292 "PRINT%RESTART", used_print_key=print_key), cp_p_file)) do_print = .true.
3294 IF (.NOT. do_print)
RETURN
3296 CALL timeset(routinen, handle)
3298 output_unit = cp_logger_get_default_io_unit()
3301 SELECT CASE (ex_type)
3302 CASE (tddfpt_spin_cons)
3303 lr_evals => donor_state%sc_evals
3304 lr_coeffs => donor_state%sc_coeffs
3307 CASE (tddfpt_spin_flip)
3308 lr_evals => donor_state%sf_evals
3309 lr_coeffs => donor_state%sf_coeffs
3312 CASE (tddfpt_singlet)
3313 lr_evals => donor_state%sg_evals
3314 lr_coeffs => donor_state%sg_coeffs
3317 CASE (tddfpt_triplet)
3318 lr_evals => donor_state%tp_evals
3319 lr_coeffs => donor_state%tp_coeffs
3324 SELECT CASE (donor_state%state_type)
3333 ndo_mo = donor_state%ndo_mo
3334 nex =
SIZE(lr_evals)
3335 CALL cp_fm_get_info(lr_coeffs, nrow_global=nao)
3336 state_type = donor_state%state_type
3337 ex_atom = donor_state%at_index
3338 mo_indices => donor_state%mo_indices
3342 my_middle =
'xasat'//trim(adjustl(cp_to_string(ex_atom)))//
'_'//trim(domo)//
'_'//trim(excite)
3343 rst_unit = cp_print_key_unit_nr(logger, xas_tdp_section,
"PRINT%RESTART", extension=
".rst", &
3344 file_status=
"REPLACE", file_action=
"WRITE", &
3345 file_form=
"UNFORMATTED", middle_name=trim(my_middle))
3347 filename = cp_print_key_generate_filename(logger, print_key, middle_name=trim(my_middle), &
3348 extension=
".rst", my_local=.false.)
3350 IF (output_unit > 0)
THEN
3351 WRITE (unit=output_unit, fmt=
"(/,T5,A,/T5,A,A,A)") &
3352 "Linear-response orbitals and excitation energies are written in: ", &
3353 '"', trim(filename),
'"'
3357 IF (rst_unit > 0)
THEN
3358 WRITE (rst_unit) ex_atom, state_type, ndo_mo, ex_type
3359 WRITE (rst_unit) nao, nex, nspins
3360 WRITE (rst_unit) mo_indices(:, :)
3361 WRITE (rst_unit) lr_evals(:)
3363 CALL cp_fm_write_unformatted(lr_coeffs, rst_unit)
3366 CALL get_qs_env(qs_env, mos=mos)
3367 DO ispin = 1, nspins
3368 CALL cp_fm_write_unformatted(mos(ispin)%mo_coeff, rst_unit)
3372 CALL cp_print_key_finished_output(rst_unit, logger, xas_tdp_section,
"PRINT%RESTART")
3374 CALL timestop(handle)
3376 END SUBROUTINE write_donor_state_restart
3385 SUBROUTINE read_donor_state_restart(donor_state, ex_type, filename, qs_env)
3387 TYPE(donor_state_type),
POINTER :: donor_state
3388 INTEGER,
INTENT(OUT) :: ex_type
3389 CHARACTER(len=*),
INTENT(IN) :: filename
3390 TYPE(qs_environment_type),
POINTER :: qs_env
3392 CHARACTER(len=*),
PARAMETER :: routinen =
'read_donor_state_restart'
3394 INTEGER :: handle, ispin, nao, nex, nspins, &
3395 output_unit, read_params(7), rst_unit
3396 INTEGER,
DIMENSION(:, :),
POINTER :: mo_indices
3397 LOGICAL :: file_exists
3398 REAL(dp),
DIMENSION(:),
POINTER :: lr_evals
3399 TYPE(cp_blacs_env_type),
POINTER :: blacs_env
3400 TYPE(cp_fm_struct_type),
POINTER :: fm_struct
3401 TYPE(cp_fm_type),
POINTER :: lr_coeffs
3402 TYPE(mo_set_type),
DIMENSION(:),
POINTER :: mos
3403 TYPE(mp_comm_type) :: group
3404 TYPE(mp_para_env_type),
POINTER :: para_env
3406 NULLIFY (lr_evals, lr_coeffs, para_env, fm_struct, blacs_env, mos)
3408 CALL timeset(routinen, handle)
3410 output_unit = cp_logger_get_default_io_unit()
3411 cpassert(
ASSOCIATED(donor_state))
3412 CALL get_qs_env(qs_env, para_env=para_env, blacs_env=blacs_env)
3415 file_exists = .false.
3418 IF (para_env%is_source())
THEN
3420 INQUIRE (file=filename, exist=file_exists)
3421 IF (.NOT. file_exists) cpabort(
"Trying to read non-existing XAS_TDP restart file")
3423 CALL open_file(file_name=trim(filename), file_action=
"READ", file_form=
"UNFORMATTED", &
3424 file_position=
"REWIND", file_status=
"OLD", unit_number=rst_unit)
3427 IF (output_unit > 0)
THEN
3428 WRITE (unit=output_unit, fmt=
"(/,T5,A,/,T5,A,A,A)") &
3429 "Reading linear-response orbitals and excitation energies from file: ", &
3434 IF (rst_unit > 0)
THEN
3435 READ (rst_unit) read_params(1:4)
3436 READ (rst_unit) read_params(5:7)
3438 CALL group%bcast(read_params)
3439 donor_state%at_index = read_params(1)
3440 donor_state%state_type = read_params(2)
3441 donor_state%ndo_mo = read_params(3)
3442 ex_type = read_params(4)
3443 nao = read_params(5)
3444 nex = read_params(6)
3445 nspins = read_params(7)
3447 ALLOCATE (mo_indices(donor_state%ndo_mo, nspins))
3448 IF (rst_unit > 0)
THEN
3449 READ (rst_unit) mo_indices(1:donor_state%ndo_mo, 1:nspins)
3451 CALL group%bcast(mo_indices)
3452 donor_state%mo_indices => mo_indices
3455 ALLOCATE (lr_evals(nex))
3456 IF (rst_unit > 0)
READ (rst_unit) lr_evals(1:nex)
3457 CALL group%bcast(lr_evals)
3460 CALL cp_fm_struct_create(fm_struct, context=blacs_env, para_env=para_env, &
3461 nrow_global=nao, ncol_global=nex*donor_state%ndo_mo*nspins)
3462 ALLOCATE (lr_coeffs)
3463 CALL cp_fm_create(lr_coeffs, fm_struct)
3464 CALL cp_fm_read_unformatted(lr_coeffs, rst_unit)
3465 CALL cp_fm_struct_release(fm_struct)
3468 CALL get_qs_env(qs_env, mos=mos)
3469 DO ispin = 1, nspins
3470 CALL cp_fm_read_unformatted(mos(ispin)%mo_coeff, rst_unit)
3474 IF (para_env%is_source())
THEN
3475 CALL close_file(unit_number=rst_unit)
3479 SELECT CASE (ex_type)
3480 CASE (tddfpt_spin_cons)
3481 donor_state%sc_evals => lr_evals
3482 donor_state%sc_coeffs => lr_coeffs
3483 CASE (tddfpt_spin_flip)
3484 donor_state%sf_evals => lr_evals
3485 donor_state%sf_coeffs => lr_coeffs
3486 CASE (tddfpt_singlet)
3487 donor_state%sg_evals => lr_evals
3488 donor_state%sg_coeffs => lr_coeffs
3489 CASE (tddfpt_triplet)
3490 donor_state%tp_evals => lr_evals
3491 donor_state%tp_coeffs => lr_coeffs
3494 CALL timestop(handle)
3496 END SUBROUTINE read_donor_state_restart
3504 SUBROUTINE restart_calculation(rst_filename, xas_tdp_section, qs_env)
3506 CHARACTER(len=*),
INTENT(IN) :: rst_filename
3507 TYPE(section_vals_type),
POINTER :: xas_tdp_section
3508 TYPE(qs_environment_type),
POINTER :: qs_env
3511 TYPE(donor_state_type),
POINTER :: donor_state
3512 TYPE(xas_tdp_env_type),
POINTER :: xas_tdp_env
3514 NULLIFY (xas_tdp_env, donor_state)
3517 ALLOCATE (donor_state)
3518 CALL donor_state_create(donor_state)
3519 CALL read_donor_state_restart(donor_state, ex_type, rst_filename, qs_env)
3522 CALL xas_tdp_env_create(xas_tdp_env)
3523 CALL xas_tdp_post(ex_type, donor_state, xas_tdp_env, xas_tdp_section, qs_env)
3526 CALL xas_tdp_env_release(xas_tdp_env)
3527 CALL free_ds_memory(donor_state)
3528 DEALLOCATE (donor_state%mo_indices)
3529 DEALLOCATE (donor_state)
3531 END SUBROUTINE restart_calculation
subroutine pbc(r, r_pbc, s, s_pbc, a, b, c, alpha, beta, gamma, debug, info, pbc0, h, hinv)
...
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 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.
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)
...
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...
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.
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_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, 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, 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, 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_r3d_rs_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_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)
...