19 USE omp_lib,
ONLY: omp_get_max_threads,&
108#include "./base/base_uses.f90"
114 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'dft_plus_u'
133 SUBROUTINE plus_u(qs_env, matrix_h, matrix_w)
137 POINTER :: matrix_h, matrix_w
139 CHARACTER(LEN=*),
PARAMETER :: routinen =
'plus_u'
141 INTEGER :: handle, output_unit, print_level
142 LOGICAL :: orthonormal_basis, should_output
147 CALL timeset(routinen, handle)
149 cpassert(
ASSOCIATED(qs_env))
151 NULLIFY (input, dft_control)
157 dft_control=dft_control)
165 orthonormal_basis = .false.
169 print_level = logger%iter_info%print_level
172 (.NOT.
PRESENT(matrix_w)))
174 extension=
".plus_u", &
175 ignore_should_output=should_output, &
176 log_filename=.false.)
180 SELECT CASE (dft_control%plus_u_method_id)
182 IF (orthonormal_basis)
THEN
185 CALL mulliken(qs_env, orthonormal_basis, matrix_h, &
186 should_output, output_unit, print_level)
188 CALL lowdin(qs_env, matrix_h, matrix_w, &
189 should_output, output_unit, print_level)
192 CALL mulliken(qs_env, orthonormal_basis, matrix_h, &
193 should_output, output_unit, print_level)
195 CALL mulliken_charges(qs_env, orthonormal_basis, matrix_h, matrix_w, &
196 should_output, output_unit, print_level)
198 CALL tensorial(qs_env, matrix_h, matrix_w, &
199 should_output, output_unit, print_level)
201 cpabort(
"Invalid DFT+U method requested")
205 ignore_should_output=should_output)
207 CALL timestop(handle)
240 SUBROUTINE lowdin(qs_env, matrix_h, matrix_w, should_output, output_unit, &
245 POINTER :: matrix_h, matrix_w
246 LOGICAL,
INTENT(IN) :: should_output
247 INTEGER,
INTENT(IN) :: output_unit, print_level
249 CHARACTER(LEN=*),
PARAMETER :: routinen =
'lowdin'
251 CHARACTER(LEN=10) :: spin_info
252 CHARACTER(LEN=6),
ALLOCATABLE,
DIMENSION(:) :: symbol
253 CHARACTER(LEN=default_string_length) :: atomic_kind_name
254 INTEGER :: atom_a, handle, i, i0, iatom, ikind, iorb, isb, iset, isgf, ishell, ispin, j, &
255 jsb, jsgf, lu, m, max_scf, n, natom_of_kind, nkind, norb, nsb, nsbsize, nset, nsgf, &
257 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: shell_sgf
258 INTEGER,
DIMENSION(1) :: iloc
259 INTEGER,
DIMENSION(:),
POINTER :: atom_list, nshell, orbitals
260 INTEGER,
DIMENSION(:, :),
POINTER :: first_sgf, l, last_sgf
261 LOGICAL :: debug, dft_plus_u_atom, do_kpoints, &
262 found, if_plus_j, just_energy, smear
263 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: orb_occ
264 REAL(kind=
dp) :: eps_scf, eps_u_ramping, fspin, hund_j, occ, perturbation_strength, sij, &
265 trq, trq2, trqxq_hund_j, u_minus_j, u_minus_j_target, u_ramping
266 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigval, q_eigval
267 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: orbq, q_eigvec, q_matrix, q_opp_matrix, &
269 REAL(kind=
dp),
CONTIGUOUS,
DIMENSION(:, :), &
270 POINTER :: local_data
271 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: q_block, q_opp_block, v_block, vhxc_block
274 TYPE(
cp_fm_type) :: fm_sev, fm_work1, fm_work2, slambda
276 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_vhxc
277 TYPE(
dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_p, matrix_s
279 TYPE(
dbcsr_type),
POINTER :: sm_h, sm_p, sm_p_opp, sm_s, sm_vhxc, sm_w
285 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
289 CALL timeset(routinen, handle)
293 NULLIFY (sm_h, sm_p, sm_p_opp, sm_s, sm_w, vhxc_block, sm_vhxc, matrix_vhxc)
301 atomic_kind_set=atomic_kind_set, &
302 qs_kind_set=qs_kind_set, &
303 dft_control=dft_control, &
304 do_kpoints=do_kpoints, &
307 matrix_s_kp=matrix_s, &
308 matrix_vhxc=matrix_vhxc, &
315 energy%dft_plus_u = 0.0_dp
317 nspin = dft_control%nspins
318 IF (dft_control%mtlr_dft_with_perturbation)
THEN
319 IF (.NOT.
ASSOCIATED(matrix_vhxc))
THEN
320 cpabort(
"MTLR requires the projected Hxc matrix for every spin channel.")
322 IF (
SIZE(matrix_vhxc) /= nspin)
THEN
323 cpabort(
"The number of projected Hxc matrices does not match the spin channels.")
336 nkind =
SIZE(atomic_kind_set)
338 IF (
PRESENT(matrix_h) .OR.
PRESENT(matrix_w))
THEN
339 just_energy = .false.
351 IF (hund_j /= 0.0_dp)
THEN
353 IF (
ASSOCIATED(orbitals))
THEN
354 CALL cp_abort(__location__,
"ENFORCE_OCCUPATION is incompatible with a nonzero Hund J "// &
355 "in the Lowdin DFT+U+J method.")
362 IF (.NOT. do_kpoints)
THEN
364 fm_s_half => scf_env%s_half
365 cpassert(
ASSOCIATED(fm_s_half))
368 CALL cp_fm_create(matrix=fm_work1, matrix_struct=fmstruct, &
369 name=
"FULL WORK MATRIX 1")
370 CALL cp_fm_create(matrix=fm_work2, matrix_struct=fmstruct, &
371 name=
"FULL WORK MATRIX 2")
377 IF (
PRESENT(matrix_w) .AND. .NOT. do_kpoints)
THEN
378 CALL cp_fm_create(matrix=fm_sev, matrix_struct=fmstruct)
379 CALL cp_fm_create(matrix=slambda, matrix_struct=fmstruct)
380 ALLOCATE (eigval(nsgf), slam(nsgf, 1))
381 sm_s => matrix_s(1, 1)%matrix
386 IF (eigval(i) > 0._dp)
THEN
387 slam(i, 1) = sqrt(eigval(i))
389 cpabort(
"S matrix not positive definit")
399 DO i = 1,
SIZE(local_data, 2)
400 DO j = 1,
SIZE(local_data, 1)
401 sij = local_data(j, i)
402 IF (sij > 0.0_dp) sij = 1.0_dp/sij
403 local_data(j, i) = sij
406 DEALLOCATE (eigval, slam)
413 IF (qs_env%scf_control%use_ot .OR. &
417 ALLOCATE (orbq(nsgf, nspin))
419 orbq(kpoints%lowdin_orbitals, :) = kpoints%lowdin_q
423 sm_s => matrix_s(1, 1)%matrix
425 IF (if_plus_j .AND. nspin == 2)
THEN
434 IF (if_plus_j .AND. nspin == 2)
THEN
439 IF (dft_control%mtlr_dft_with_perturbation)
THEN
440 IF (ispin == 1) perturbation_strength = 0.9_dp*dft_control%perturbation_strength
441 IF (ispin == 2) perturbation_strength = 1.1_dp*dft_control%perturbation_strength
442 IF (.NOT.
ASSOCIATED(matrix_vhxc(ispin)%matrix))
THEN
443 cpabort(
"MTLR projected Hxc matrix is not initialized.")
445 sm_vhxc => matrix_vhxc(ispin)%matrix
450 IF (if_plus_j .AND. nspin == 2)
CALL dbcsr_set_diag(sm_q_opp, orbq(:, 3 - ispin))
453 sm_p => matrix_p(ispin, 1)%matrix
461 matrix_a=fm_s_half, &
467 output_unit=output_unit)
469 output_unit=output_unit)
471 output_unit=output_unit)
480 IF (if_plus_j .AND. nspin == 2)
THEN
483 sm_p_opp => matrix_p(3 - ispin, 1)%matrix
491 matrix_a=fm_s_half, &
511 atom_list=atom_list, &
512 name=atomic_kind_name, &
516 dft_plus_u_atom=dft_plus_u_atom, &
517 l_of_dft_plus_u=lu, &
519 basis_set=orb_basis_set, &
520 u_minus_j=u_minus_j, &
522 u_minus_j_target=u_minus_j_target, &
523 u_ramping=u_ramping, &
524 eps_u_ramping=eps_u_ramping, &
531 IF (.NOT.
ASSOCIATED(orb_basis_set)) cycle
532 IF (.NOT. dft_plus_u_atom) cycle
536 IF ((ispin == 1) .AND. (u_ramping > 0.0_dp) .AND. .NOT. do_kpoints)
THEN
537 IF (qs_env%scf_env%iter_delta <= eps_u_ramping)
THEN
538 u_minus_j = min(u_minus_j + u_ramping, u_minus_j_target)
539 CALL set_qs_kind(qs_kind_set(ikind), u_minus_j=u_minus_j)
541 IF (should_output .AND. (output_unit > 0))
THEN
542 WRITE (unit=output_unit, fmt=
"(T3,A,3X,A,F0.3,A)") &
543 "Kind name: "//trim(adjustl(atomic_kind_name)), &
544 "U(eff) = ", u_minus_j*
evolt,
" eV"
548 IF (u_minus_j == 0.0_dp .AND. hund_j == 0.0_dp) cycle
552 first_sgf=first_sgf, &
559 ALLOCATE (shell_sgf(nsgf_kind))
562 DO ishell = 1, nshell(iset)
563 IF (l(ishell, iset) /= lu) cycle
564 DO isgf = first_sgf(ishell, iset), last_sgf(ishell, iset)
573 ALLOCATE (q_matrix(n, n))
574 q_matrix(:, :) = 0.0_dp
576 IF (hund_j /= 0.0_dp .AND. nspin == 2)
THEN
577 ALLOCATE (q_opp_matrix(n, n))
578 q_opp_matrix(:, :) = 0.0_dp
581 IF (dft_control%mtlr_dft_with_perturbation .AND. &
582 dft_control%mtlr_ikind == ikind)
THEN
583 dft_control%vhxc(ispin) = 0.0_dp
584 dft_control%trq(ispin) = 0.0_dp
589 IF (output_unit > 0)
THEN
590 ALLOCATE (symbol(nsbsize))
595 WRITE (unit=spin_info, fmt=
"(A8,I2)")
" of spin", ispin
599 WRITE (unit=output_unit, fmt=
"(/,T3,A,I0,A,/,/,T5,A,10(2X,A6))") &
600 "DFT+U occupations"//trim(spin_info)//
" for the atoms of atomic kind ", ikind, &
601 ": "//trim(atomic_kind_name), &
602 "Atom Shell ", (adjustr(symbol(i)), i=1, nsbsize),
" Trace"
608 DO iatom = 1, natom_of_kind
609 atom_a = atom_list(iatom)
610 q_matrix(:, :) = 0.0_dp
611 IF (
ALLOCATED(q_opp_matrix))
THEN
612 q_opp_matrix(:, :) = 0.0_dp
621 IF (hund_j /= 0.0_dp .AND. nspin == 2)
THEN
628 IF (dft_control%mtlr_dft_with_perturbation .AND. &
629 dft_control%mtlr_ikind == ikind .AND. &
630 qs_kind_set(ikind)%dft_plus_u%lr_atom == atom_a)
THEN
638 IF (
ASSOCIATED(q_block))
THEN
642 q_matrix(i, i) = q_block(isgf, isgf)
643 IF (hund_j /= 0.0_dp .AND. nspin == 2 .AND.
ASSOCIATED(q_opp_block))
THEN
644 q_opp_matrix(i, i) = q_opp_block(isgf, isgf)
646 IF (
ASSOCIATED(vhxc_block) .AND. dft_control%mtlr_dft_with_perturbation .AND. &
647 dft_control%mtlr_ikind == ikind .AND. qs_kind_set(ikind)%dft_plus_u%lr_atom == atom_a)
THEN
648 dft_control%vhxc(ispin) = dft_control%vhxc(ispin) + vhxc_block(isgf, isgf)
649 dft_control%trq(ispin) = dft_control%trq(ispin) + q_block(isgf, isgf)
654 IF (
ASSOCIATED(orbitals))
THEN
655 IF ((qs_env%scf_env%iter_delta >= eps_scf) .OR. &
656 ((qs_env%scf_env%outer_scf%iter_count == 0) .AND. &
657 (qs_env%scf_env%iter_count <= max_scf)))
THEN
658 ALLOCATE (orb_occ(nsbsize))
659 ALLOCATE (q_eigval(n))
661 ALLOCATE (q_eigvec(n, n))
662 q_eigvec(:, :) = 0.0_dp
663 norb =
SIZE(orbitals)
664 CALL jacobi(q_matrix, q_eigval, q_eigvec)
665 q_matrix(:, :) = 0.0_dp
668 DO i = (isb - 1)*nsbsize + 1, isb*nsbsize
669 trq = trq + q_eigval(i)
672 occ = trq/real(norb, kind=
dp)
677 iloc = maxloc(q_eigvec(:, isb*nsbsize))
678 jsb = int((iloc(1) - 1)/nsbsize) + 1
680 i0 = (jsb - 1)*nsbsize + 1
682 DO j = i0, jsb*nsbsize
686 IF (.NOT. orb_occ(lu + m + 1))
THEN
688 orb_occ(lu + m + 1) = .true.
692 iorb = i0 + lu + orbitals(i)
693 orb_occ(lu + orbitals(i) + 1) = .true.
695 cpassert(iorb /= -1000)
696 iloc = maxloc(q_eigvec(iorb, :))
697 q_eigval(iloc(1)) = min(occ, trq)
698 q_matrix(:, iloc(1)) = q_eigval(iloc(1))*q_eigvec(:, iloc(1))
699 trq = trq - q_eigval(iloc(1))
702 q_matrix(:, :) = matmul(q_matrix, transpose(q_eigvec))
704 DEALLOCATE (q_eigval)
705 DEALLOCATE (q_eigvec)
709 trq = fspin*sum([(q_matrix(i, i), i=1, n)])
710 trq2 = fspin*fspin*sum(q_matrix*transpose(q_matrix))
711 trqxq_hund_j = 0.0_dp
712 IF (hund_j /= 0.0_dp)
THEN
714 trqxq_hund_j = sum(q_matrix*transpose(q_opp_matrix))
716 trqxq_hund_j = sum(q_matrix*transpose(q_matrix))
721 energy%dft_plus_u = energy%dft_plus_u + 0.5_dp*u_minus_j*(trq - trq2)/fspin
722 IF (hund_j /= 0.0_dp)
THEN
723 trqxq_hund_j = fspin*fspin*trqxq_hund_j
724 energy%dft_plus_u = energy%dft_plus_u + 0.5_dp*hund_j*trqxq_hund_j/fspin
728 IF (.NOT. just_energy)
THEN
734 cpassert(
ASSOCIATED(v_block))
741 v_block(isgf, isgf) = u_minus_j*(0.5_dp - fspin*q_matrix(i, i))
742 IF (dft_control%mtlr_dft_with_perturbation .AND. &
743 dft_control%mtlr_ikind == ikind .AND. &
744 qs_kind_set(ikind)%dft_plus_u%lr_atom == atom_a)
THEN
745 v_block(isgf, isgf) = v_block(isgf, isgf) + perturbation_strength
748 cpassert(abs(q_matrix(j, i)) < 1.0e-14_dp)
749 IF (hund_j /= 0.0_dp .AND. nspin == 2)
THEN
750 cpassert(abs(q_opp_matrix(j, i)) < 1.0e-14_dp)
752 v_block(isgf, jsgf) = -u_minus_j*fspin*q_matrix(j, i)
754 IF (hund_j /= 0.0_dp)
THEN
756 v_block(isgf, jsgf) = v_block(isgf, jsgf) + hund_j*fspin*q_opp_matrix(j, i)
758 v_block(isgf, jsgf) = v_block(isgf, jsgf) + hund_j*fspin*q_matrix(j, i)
769 CALL para_env%sum(q_matrix)
770 IF (output_unit > 0)
THEN
771 ALLOCATE (q_work(nsb, nsbsize))
772 q_work(:, :) = 0.0_dp
775 DO i = (isb - 1)*nsbsize + 1, isb*nsbsize
777 q_work(isb, j) = q_matrix(i, i)
781 WRITE (unit=output_unit, fmt=
"(T3,I6,2X,I6,2X,10F8.3)") &
782 atom_a, isb, q_work(isb, :), sum(q_work(isb, :))
784 WRITE (unit=output_unit, fmt=
"(T12,A,2X,10F8.3)") &
785 "Total", (sum(q_work(:, i)), i=1, nsbsize), sum(q_work)
786 WRITE (unit=output_unit, fmt=
"(A)")
""
790 WRITE (unit=output_unit, fmt=
"(T9,70I10)") (i, i=1, n)
792 WRITE (unit=output_unit, fmt=
"(T3,I6,70F10.6)") i, q_matrix(i, :)
795 ALLOCATE (q_eigval(n))
797 ALLOCATE (q_eigvec(n, n))
798 q_eigvec(:, :) = 0.0_dp
799 CALL jacobi(q_matrix, q_eigval, q_eigvec)
800 WRITE (unit=output_unit, fmt=
"(/,T9,70I10)") (i, i=1, n)
801 WRITE (unit=output_unit, fmt=
"(T9,71F10.6)") (q_eigval(i), i=1, n), &
804 WRITE (unit=output_unit, fmt=
"(T3,I6,70F10.6)") i, q_eigvec(i, :)
806 DEALLOCATE (q_eigval)
807 DEALLOCATE (q_eigvec)
812 ALLOCATE (q_work(nsgf_kind, nsgf_kind))
813 q_work(:, :) = 0.0_dp
814 IF (
ASSOCIATED(q_block)) q_work(:, :) = q_block(:, :)
815 CALL para_env%sum(q_work)
816 IF (output_unit > 0)
THEN
817 norb =
SIZE(q_work, 1)
818 WRITE (unit=output_unit, fmt=
"(/,T9,200I10)") (i, i=1, norb)
820 WRITE (unit=output_unit, fmt=
"(T3,I6,200F10.6)") i, q_work(i, :)
822 ALLOCATE (q_eigval(norb))
824 ALLOCATE (q_eigvec(norb, norb))
825 q_eigvec(:, :) = 0.0_dp
826 CALL jacobi(q_work, q_eigval, q_eigvec)
827 WRITE (unit=output_unit, fmt=
"(/,T9,200I10)") (i, i=1, norb)
828 WRITE (unit=output_unit, fmt=
"(T9,201F10.6)") (q_eigval(i), i=1, norb), &
829 sum(q_eigval(1:norb))
831 WRITE (unit=output_unit, fmt=
"(T3,I6,200F10.6)") i, q_eigvec(i, :)
833 DEALLOCATE (q_eigval)
834 DEALLOCATE (q_eigvec)
842 IF (dft_control%mtlr_dft_with_perturbation .AND. &
843 dft_control%mtlr_ikind == ikind)
THEN
844 dft_control%vhxc(ispin) = dft_control%vhxc(ispin)/real(n,
dp)
845 CALL para_env%sum(dft_control%vhxc(ispin))
846 CALL para_env%sum(dft_control%trq(ispin))
849 DEALLOCATE (shell_sgf, q_matrix)
851 IF (
ALLOCATED(q_opp_matrix))
THEN
852 DEALLOCATE (q_opp_matrix)
858 IF (
PRESENT(matrix_h) .OR. (
PRESENT(matrix_w) .AND. do_kpoints))
THEN
861 REAL(
dp) :: diagonal(nsgf)
863 CALL para_env%sum(diagonal)
864 kpoints%lowdin_v(:, ispin) = diagonal(kpoints%lowdin_orbitals)
867 sm_h => matrix_h(ispin, 1)%matrix
876 IF (
PRESENT(matrix_w) .AND. .NOT. do_kpoints)
THEN
878 sm_p => matrix_p(ispin, 1)%matrix
879 sm_w => matrix_w(ispin, 1)%matrix
884 CALL parallel_gemm(
'N',
'N', nsgf, nsgf, nsgf, 1.0_dp, fm_work1, fm_sev, 0.0_dp, fm_work2)
885 CALL parallel_gemm(
'T',
'N', nsgf, nsgf, nsgf, 1.0_dp, fm_sev, fm_work2, 0.0_dp, fm_work1)
890 CALL parallel_gemm(
'N',
'N', nsgf, nsgf, nsgf, -1.0_dp, fm_sev, fm_work2, 0.0_dp, fm_work1)
897 IF (
PRESENT(matrix_w))
THEN
905 CALL para_env%sum(energy%dft_plus_u)
907 IF (energy%dft_plus_u < 0.0_dp)
THEN
908 CALL cp_warn(__location__, &
909 "DFT+U energy contribution is negative possibly due "// &
910 "to unphysical Lowdin charges!")
922 IF (if_plus_j .AND. nspin == 2)
THEN
926 CALL timestop(handle)
928 END SUBROUTINE lowdin
935 TYPE(qs_environment_type),
POINTER :: qs_env
937 INTEGER :: i, ia, ik, ikind, iset, ish, lu, m, nao, &
939 INTEGER,
ALLOCATABLE :: first_atom(:)
940 INTEGER,
POINTER :: atoms(:), first(:, :), l(:, :), &
941 last(:, :), nshell(:), orbitals(:)
943 LOGICAL,
ALLOCATABLE :: selected(:)
944 REAL(kind=dp) :: j, u
945 TYPE(atomic_kind_type),
POINTER :: kinds_set(:)
946 TYPE(dft_control_type),
POINTER :: dft_control
947 TYPE(gto_basis_set_type),
POINTER :: basis
948 TYPE(kpoint_env_type),
POINTER :: kp
949 TYPE(kpoint_type),
POINTER :: kpoints
950 TYPE(particle_type),
POINTER :: particles(:)
951 TYPE(qs_kind_type),
POINTER :: qs_kinds(:)
953 CALL get_qs_env(qs_env, kpoints=kpoints, atomic_kind_set=kinds_set, qs_kind_set=qs_kinds, &
954 particle_set=particles, dft_control=dft_control)
955 IF (dft_control%mtlr_dft_with_perturbation)
THEN
956 cpabort(
"MTLR with Lowdin DFT+U and k-points is not implemented")
958 DO ik = 1,
SIZE(kpoints%kp_sym)
959 IF (kpoints%kp_sym(ik)%kpoint_sym%apply_symmetry)
THEN
960 cpabort(
"Lowdin DFT+U requires a full k-point grid or time-reversal-only reduction")
963 CALL get_qs_kind_set(qs_kinds, nsgf=nao)
964 nspin = dft_control%nspins
965 ALLOCATE (first_atom(
SIZE(particles)), selected(nao))
966 CALL get_particle_set(particles, qs_kinds, first_sgf=first_atom)
968 DO ikind = 1,
SIZE(qs_kinds)
970 CALL get_qs_kind(qs_kinds(ikind), dft_plus_u_atom=active, l_of_dft_plus_u=lu, &
971 basis_set=basis, u_minus_j_target=u, hund_j=j, orbitals=orbitals)
972 IF (.NOT. active) cycle
973 IF (
ASSOCIATED(orbitals))
THEN
974 cpabort(
"Lowdin DFT+U with k-points does not support ENFORCE_OCCUPATION")
976 IF (u == 0.0_dp .AND. j == 0.0_dp) cycle
977 CALL get_atomic_kind(kinds_set(ikind), atom_list=atoms)
978 CALL get_gto_basis_set(basis, first_sgf=first, last_sgf=last, l=l, nset=nset, nshell=nshell)
979 DO ia = 1,
SIZE(atoms)
981 DO ish = 1, nshell(iset)
982 IF (l(ish, iset) /= lu) cycle
983 selected(first_atom(atoms(ia)) + first(ish, iset) - 1: &
984 first_atom(atoms(ia)) + last(ish, iset) - 1) = .true.
989 IF (
ALLOCATED(kpoints%lowdin_orbitals))
THEN
990 DEALLOCATE (kpoints%lowdin_orbitals, kpoints%lowdin_q, kpoints%lowdin_q_new, kpoints%lowdin_v)
993 ALLOCATE (kpoints%lowdin_orbitals(m))
994 kpoints%lowdin_orbitals(:) = pack([(i, i=1, nao)], selected)
995 ALLOCATE (kpoints%lowdin_q(m, nspin), kpoints%lowdin_q_new(m, nspin), kpoints%lowdin_v(m, nspin))
996 kpoints%lowdin_q(:, :) = 0.0_dp
997 kpoints%lowdin_q_new(:, :) = 0.0_dp
998 kpoints%lowdin_v(:, :) = 0.0_dp
999 kpoints%lowdin_density_ready = .false.
1000 kpoints%lowdin_population_ready = .false.
1001 DO ik = 1,
SIZE(kpoints%kp_env)
1002 kp => kpoints%kp_env(ik)%kpoint_env
1015 TYPE(kpoint_env_type),
POINTER :: kp
1016 INTEGER,
INTENT(IN) :: orbitals(:)
1017 LOGICAL,
INTENT(IN) :: use_real_wfn
1018 TYPE(cp_cfm_type),
INTENT(IN),
OPTIONAL :: smat
1021 REAL(dp),
ALLOCATABLE :: eigenvalues(:)
1022 TYPE(cp_cfm_type) :: evec, work
1024 CALL cp_fm_release(kp%lowdin_b)
1025 CALL cp_fm_release(kp%lowdin_work)
1026 CALL cp_cfm_release(kp%lowdin_cb)
1027 CALL cp_cfm_release(kp%lowdin_cwork)
1028 CALL kp%lowdin_gemm%destroy()
1031 IF (
PRESENT(smat))
THEN
1032 cpassert(.NOT. use_real_wfn)
1033 CALL cp_cfm_get_info(smat, nrow_global=n)
1034 ALLOCATE (eigenvalues(n))
1035 CALL cp_cfm_create(evec, smat%matrix_struct)
1036 CALL cp_cfm_create(work, smat%matrix_struct)
1037 CALL cp_cfm_release(kp%cshalf)
1038 CALL cp_cfm_create(kp%cshalf, smat%matrix_struct)
1039 CALL cp_cfm_to_cfm(smat, work)
1040 CALL cp_cfm_heevd(work, evec, eigenvalues)
1041 cpassert(all(eigenvalues >= 0.0_dp))
1042 CALL cp_cfm_to_cfm(evec, work)
1043 CALL cp_cfm_column_scale(work, cmplx(sqrt(eigenvalues), 0.0_dp, dp))
1044 CALL parallel_gemm(
'N',
'C', n, n, n, z_one, work, evec, z_zero, kp%cshalf)
1045 CALL cp_cfm_release(evec)
1046 CALL cp_cfm_release(work)
1048 CALL kp%lowdin_gemm%create(local_gemm_pu_gpu, timing=.false.)
1049 IF (use_real_wfn)
THEN
1050 CALL cp_fm_create(kp%lowdin_b, kp%shalf%matrix_struct, ncol=m)
1051 CALL cp_fm_create(kp%lowdin_work, kp%lowdin_b%matrix_struct)
1053 CALL cp_fm_to_fm(kp%shalf, kp%lowdin_b, 1, orbitals(i), i)
1056 CALL cp_cfm_create(kp%lowdin_cb, kp%lowdin_b%matrix_struct)
1057 CALL cp_fm_to_cfm(kp%lowdin_b, mtarget=kp%lowdin_cb)
1059 CALL cp_cfm_create(kp%lowdin_cb, kp%cshalf%matrix_struct, ncol=m)
1061 CALL cp_cfm_to_cfm(kp%cshalf, kp%lowdin_cb, 1, orbitals(i), i)
1064 CALL cp_cfm_create(kp%lowdin_cwork, kp%lowdin_cb%matrix_struct)
1065 IF (
PRESENT(smat))
CALL cp_cfm_release(kp%cshalf)
1074 TYPE(qs_environment_type),
POINTER :: qs_env
1075 TYPE(cp_fm_type),
INTENT(IN) :: fmwork
1077 INTEGER :: ik, ispin, kplocal, kpmax
1078 TYPE(cp_cfm_type) :: cpmat
1079 TYPE(cp_fm_type) :: pmat
1080 TYPE(dbcsr_p_type),
POINTER :: density(:, :)
1081 TYPE(kpoint_env_type),
POINTER :: kp
1082 TYPE(kpoint_operator_context_type) :: ctx
1083 TYPE(kpoint_type),
POINTER :: kpoints
1084 TYPE(qs_rho_type),
POINTER :: rho
1086 CALL get_qs_env(qs_env, kpoints=kpoints, rho=rho)
1087 IF (.NOT.
ALLOCATED(kpoints%lowdin_orbitals))
RETURN
1088 IF (.NOT. kpoints%lowdin_density_ready .AND.
SIZE(kpoints%lowdin_orbitals) > 0)
THEN
1091 CALL qs_rho_get(rho, rho_ao_kp=density)
1092 CALL kpoint_operator_context_create(ctx, kpoints, fmwork,
SIZE(density, 1))
1093 kp => kpoints%kp_env(1)%kpoint_env
1094 IF (kpoints%use_real_wfn)
THEN
1095 CALL cp_fm_create(pmat, kp%shalf%matrix_struct)
1097 CALL cp_cfm_create(cpmat, kp%cshalf%matrix_struct)
1099 kplocal =
SIZE(kpoints%kp_env)
1100 kpmax = maxval(kpoints%kp_dist(2, :) - kpoints%kp_dist(1, :) + 1)
1101 kpoints%lowdin_q_new(:, :) = 0.0_dp
1103 DO ispin = 1,
SIZE(density, 1)
1104 IF (kpoints%use_real_wfn)
THEN
1105 CALL kpoint_operator_get(ctx, ik, ispin, density, fm_re=pmat, matrix_row=ispin)
1107 CALL kpoint_operator_get(ctx, ik, ispin, density, cmat=cpmat, matrix_row=ispin)
1109 IF (ik > kplocal) cycle
1110 kp => kpoints%kp_env(ik)%kpoint_env
1111 IF (kpoints%use_real_wfn)
THEN
1112 CALL lowdin_kp_accumulate(kp, kpoints%lowdin_q_new(:, ispin), pmat=pmat)
1114 CALL lowdin_kp_accumulate(kp, kpoints%lowdin_q_new(:, ispin), cpmat=cpmat)
1118 CALL kpoints%para_env%sum(kpoints%lowdin_q_new)
1119 CALL kpoint_operator_context_release(ctx)
1120 CALL cp_fm_release(pmat)
1121 CALL cp_cfm_release(cpmat)
1122 kpoints%lowdin_population_ready = .true.
1134 TYPE(kpoint_type),
OPTIONAL,
POINTER :: kpoints
1135 REAL(kind=dp),
INTENT(INOUT),
OPTIONAL :: delta
1136 REAL(kind=dp),
INTENT(IN),
OPTIONAL :: alpha
1138 IF (.NOT.
PRESENT(kpoints))
RETURN
1139 IF (.NOT.
ASSOCIATED(kpoints))
RETURN
1140 IF (.NOT.
ALLOCATED(kpoints%lowdin_q))
RETURN
1141 IF (.NOT. kpoints%lowdin_population_ready)
THEN
1142 IF (
SIZE(kpoints%lowdin_q) > 0)
THEN
1143 cpassert(kpoints%lowdin_density_ready)
1144 CALL lowdin_kp_project(kpoints, kpoints%lowdin_q_new)
1146 kpoints%lowdin_population_ready = .true.
1148 IF (
PRESENT(delta)) delta = max(delta, maxval(abs(kpoints%lowdin_q_new - kpoints%lowdin_q)))
1149 IF (
PRESENT(alpha))
THEN
1150 IF (alpha == 1.0_dp)
THEN
1151 kpoints%lowdin_q(:, :) = kpoints%lowdin_q_new
1152 ELSE IF (alpha /= 0.0_dp)
THEN
1153 kpoints%lowdin_q(:, :) = (1.0_dp - alpha)*kpoints%lowdin_q + alpha*kpoints%lowdin_q_new
1164 SUBROUTINE lowdin_kp_project(kpoints, q, density)
1165 TYPE(kpoint_type),
POINTER :: kpoints
1166 REAL(kind=dp),
CONTIGUOUS,
INTENT(OUT) :: q(:, :)
1167 TYPE(cp_fm_type),
INTENT(IN),
OPTIONAL :: density(:, :, :)
1169 INTEGER :: handle, ik, ispin, kplocal, m, nspin, &
1171 TYPE(cp_cfm_type),
ALLOCATABLE :: work(:)
1172 TYPE(kpoint_env_type),
POINTER :: kp
1176 CALL timeset(
"lowdin_kp_population", handle)
1178 kplocal =
SIZE(kpoints%kp_env)
1179 kp => kpoints%kp_env(1)%kpoint_env
1182 ALLOCATE (work(nworkers))
1184 IF (
PRESENT(density) .OR. .NOT. kpoints%use_real_wfn)
THEN
1185 DO thread = 1, nworkers
1186 CALL cp_cfm_create(work(thread), kp%pmat(1, 1)%matrix_struct)
1194 kp => kpoints%kp_env(ik)%kpoint_env
1196 IF (
PRESENT(density))
THEN
1197 CALL cp_fm_to_cfm(density(ik, 1, ispin), density(ik, 2, ispin), work(thread))
1198 CALL lowdin_kp_accumulate(kp, q(:, ispin), cpmat=work(thread))
1199 ELSE IF (kpoints%use_real_wfn)
THEN
1200 CALL lowdin_kp_accumulate(kp, q(:, ispin), pmat=kp%pmat(1, ispin))
1202 CALL cp_fm_to_cfm(kp%pmat(1, ispin), kp%pmat(2, ispin), work(thread))
1203 CALL lowdin_kp_accumulate(kp, q(:, ispin), cpmat=work(thread))
1209 CALL kpoints%para_env%sum(q)
1210 DO thread = 1, nworkers
1211 CALL cp_cfm_release(work(thread))
1213 CALL timestop(handle)
1214 END SUBROUTINE lowdin_kp_project
1223 SUBROUTINE lowdin_kp_accumulate(kp, q, pmat, cpmat)
1224 TYPE(kpoint_env_type),
POINTER :: kp
1225 REAL(kind=dp),
INTENT(INOUT) :: q(:)
1226 TYPE(cp_fm_type),
INTENT(IN),
OPTIONAL :: pmat
1227 TYPE(cp_cfm_type),
INTENT(IN),
OPTIONAL :: cpmat
1229 INTEGER :: j, m, n, nc, nr
1230 INTEGER,
POINTER :: columns(:)
1234 cpassert(
PRESENT(pmat) .NEQV.
PRESENT(cpmat))
1235 IF (
PRESENT(pmat))
THEN
1236 CALL cp_fm_get_info(kp%lowdin_b, nrow_global=n, nrow_local=nr, ncol_local=nc, col_indices=columns)
1237 local = product(kp%lowdin_b%matrix_struct%context%num_pe) == 1
1239 CALL kp%lowdin_gemm%gemm(
'N',
'N', n, m, n, 1.0_dp, pmat%local_data,
SIZE(pmat%local_data, 1), &
1240 kp%lowdin_b%local_data,
SIZE(kp%lowdin_b%local_data, 1), 0.0_dp, &
1241 kp%lowdin_work%local_data,
SIZE(kp%lowdin_work%local_data, 1))
1243 CALL parallel_gemm(
'N',
'N', n, m, n, 1.0_dp, pmat, kp%lowdin_b, 0.0_dp, kp%lowdin_work)
1246 q(columns(j)) = q(columns(j)) + kp%wkp* &
1247 sum(kp%lowdin_b%local_data(:nr, j)*kp%lowdin_work%local_data(:nr, j))
1250 CALL cp_cfm_get_info(kp%lowdin_cb, nrow_global=n, nrow_local=nr, ncol_local=nc, col_indices=columns)
1251 CALL lowdin_kp_gemm(
'N',
'N', n, m, n, cpmat, kp%lowdin_cb, z_zero, kp%lowdin_cwork, kp%lowdin_gemm)
1253 q(columns(j)) = q(columns(j)) + kp%wkp*real(sum(conjg(kp%lowdin_cb%local_data(:nr, j))* &
1254 kp%lowdin_cwork%local_data(:nr, j)), dp)
1257 END SUBROUTINE lowdin_kp_accumulate
1267 TYPE(kpoint_env_type),
POINTER :: kp
1268 REAL(kind=dp),
INTENT(IN) :: v(:)
1269 TYPE(cp_fm_type),
INTENT(INOUT),
OPTIONAL :: rmat
1270 TYPE(cp_cfm_type),
INTENT(INOUT),
OPTIONAL :: cmat
1272 INTEGER :: j, m, n, nc, nr
1273 INTEGER,
POINTER :: columns(:)
1278 IF (all(v == 0.0_dp))
RETURN
1279 cpassert(
PRESENT(rmat) .NEQV.
PRESENT(cmat))
1280 IF (
PRESENT(rmat))
THEN
1281 CALL cp_fm_get_info(kp%lowdin_b, nrow_global=n, nrow_local=nr, ncol_local=nc, col_indices=columns)
1283 kp%lowdin_work%local_data(:nr, j) = v(columns(j))*kp%lowdin_b%local_data(:nr, j)
1285 local = product(kp%lowdin_b%matrix_struct%context%num_pe) == 1
1287 CALL kp%lowdin_gemm%gemm(
'N',
'T', n, n, m, 1.0_dp, &
1288 kp%lowdin_work%local_data,
SIZE(kp%lowdin_work%local_data, 1), &
1289 kp%lowdin_b%local_data,
SIZE(kp%lowdin_b%local_data, 1), 1.0_dp, &
1290 rmat%local_data,
SIZE(rmat%local_data, 1))
1292 CALL parallel_gemm(
'N',
'T', n, n, m, 1.0_dp, kp%lowdin_work, kp%lowdin_b, 1.0_dp, rmat)
1295 CALL cp_cfm_get_info(kp%lowdin_cb, nrow_global=n, nrow_local=nr, ncol_local=nc, col_indices=columns)
1297 kp%lowdin_cwork%local_data(:nr, j) = v(columns(j))*kp%lowdin_cb%local_data(:nr, j)
1299 CALL lowdin_kp_gemm(
'N',
'C', n, n, m, kp%lowdin_cwork, kp%lowdin_cb, z_one, cmat, kp%lowdin_gemm)
1311 TYPE(kpoint_env_type),
POINTER :: kp
1312 REAL(kind=dp),
INTENT(IN) :: v(:)
1313 TYPE(cp_cfm_type),
INTENT(IN) :: coeff
1314 TYPE(cp_cfm_type),
INTENT(INOUT) :: hc
1316 INTEGER :: i, m, n, nc, nmo, nr
1317 INTEGER,
POINTER :: rows(:)
1318 TYPE(cp_cfm_type) :: projected
1321 IF (m == 0 .OR. all(v == 0.0_dp))
RETURN
1322 CALL cp_cfm_get_info(coeff, nrow_global=n, ncol_global=nmo)
1323 CALL cp_cfm_create(projected, coeff%matrix_struct, nrow=m)
1324 CALL lowdin_kp_gemm(
'C',
'N', m, nmo, n, kp%lowdin_cb, coeff, z_zero, projected, kp%lowdin_gemm)
1325 CALL cp_cfm_get_info(projected, nrow_local=nr, ncol_local=nc, row_indices=rows)
1327 projected%local_data(i, :nc) = v(rows(i))*projected%local_data(i, :nc)
1329 CALL lowdin_kp_gemm(
'N',
'N', n, nmo, m, kp%lowdin_cb, projected, z_one, hc, kp%lowdin_gemm)
1330 CALL cp_cfm_release(projected)
1340 TYPE(qs_environment_type),
POINTER :: qs_env
1341 TYPE(cp_fm_type),
INTENT(IN) :: density(:, :, :)
1342 REAL(kind=dp),
ALLOCATABLE,
INTENT(OUT) :: response(:, :)
1344 INTEGER :: i, iatom, ikind, m, nspin
1345 INTEGER,
ALLOCATABLE :: last(:)
1346 REAL(kind=dp) :: j, u
1347 TYPE(kpoint_type),
POINTER :: kpoints
1348 TYPE(particle_type),
POINTER :: particles(:)
1349 TYPE(qs_kind_type),
POINTER :: qs_kinds(:)
1351 CALL get_qs_env(qs_env, kpoints=kpoints, particle_set=particles, qs_kind_set=qs_kinds)
1352 m =
SIZE(kpoints%lowdin_orbitals)
1353 nspin =
SIZE(density, 3)
1354 ALLOCATE (response(m, nspin))
1355 response(:, :) = 0.0_dp
1357 CALL lowdin_kp_project(kpoints, response, density)
1358 ALLOCATE (last(
SIZE(particles)))
1359 CALL get_particle_set(particles, qs_kinds, last_sgf=last)
1362 DO WHILE (kpoints%lowdin_orbitals(i) > last(iatom))
1365 CALL get_atomic_kind(particles(iatom)%atomic_kind, kind_number=ikind)
1366 CALL get_qs_kind(qs_kinds(ikind), u_minus_j=u, hund_j=j)
1367 response(i, :) = 0.5_dp*real(nspin, dp)*(j*response(i, nspin:1:-1) - u*response(i, :))
1380 TYPE(kpoint_type),
POINTER :: kpoints
1382 INTEGER :: handle, ik, ispin, iw, nworkers, thread
1383 TYPE(cp_cfm_type),
ALLOCATABLE :: work(:, :)
1384 TYPE(kpoint_env_type),
POINTER :: kp
1385 TYPE(local_gemm_ctxt_type),
ALLOCATABLE :: gemm(:)
1387 IF (
SIZE(kpoints%lowdin_orbitals) == 0)
RETURN
1388 IF (all(kpoints%lowdin_v == 0.0_dp))
RETURN
1389 CALL timeset(
"lowdin_kp_forces", handle)
1393 ALLOCATE (work(3, nworkers), gemm(nworkers))
1394 kp => kpoints%kp_env(1)%kpoint_env
1395 DO thread = 1, nworkers
1397 CALL cp_cfm_create(work(iw, thread), kp%pmat(1, 1)%matrix_struct)
1399 CALL cp_cfm_create(work(3, thread), kp%lowdin_cb%matrix_struct)
1400 CALL gemm(thread)%create(local_gemm_pu_gpu, timing=.false.)
1404 DO ispin = 1,
SIZE(kpoints%lowdin_v, 2)
1405 DO ik = 1,
SIZE(kpoints%kp_env)
1408 CALL lowdin_kp_force_matrix(kpoints%kp_env(ik)%kpoint_env, kpoints%lowdin_orbitals, ispin, &
1409 kpoints%lowdin_v(:, ispin), work(:, thread), gemm(thread))
1413 DO thread = 1, nworkers
1414 CALL gemm(thread)%destroy()
1416 CALL cp_cfm_release(work(iw, thread))
1419 CALL timestop(handle)
1431 SUBROUTINE lowdin_kp_force_matrix(kp, orbitals, ispin, v, work, gemm)
1432 TYPE(kpoint_env_type),
POINTER :: kp
1433 INTEGER,
INTENT(IN) :: orbitals(:), ispin
1434 REAL(kind=dp),
INTENT(IN) :: v(:)
1435 TYPE(cp_cfm_type),
INTENT(INOUT) :: work(3)
1436 TYPE(local_gemm_ctxt_type),
INTENT(INOUT) :: gemm
1438 COMPLEX(KIND=dp) :: value
1439 INTEGER :: i, j, m, n, nc, nr
1440 INTEGER,
POINTER :: columns(:), rows(:)
1441 LOGICAL :: local, real_only
1443 IF (all(v == 0.0_dp))
RETURN
1444 cpassert(
ALLOCATED(kp%lowdin_sqrt))
1445 cpassert(
ASSOCIATED(kp%lowdin_evec%local_data))
1446 cpassert(
ASSOCIATED(kp%wmat))
1447 CALL cp_cfm_get_info(work(1), nrow_global=n, nrow_local=nr, ncol_local=nc, &
1448 row_indices=rows, col_indices=columns)
1450 local = product(work(1)%matrix_struct%context%num_pe) == 1
1451 real_only =
SIZE(kp%pmat, 1) == 1
1453 CALL cp_fm_to_cfm(kp%pmat(1, ispin), mtarget=work(1))
1455 CALL cp_fm_to_cfm(kp%pmat(1, ispin), kp%pmat(2, ispin), work(1))
1459 CALL lowdin_kp_gemm(
'N',
'N', n, m, n, work(1), kp%lowdin_cb, z_zero, work(2), gemm)
1460 CALL lowdin_kp_gemm(
'C',
'N', n, m, n, kp%lowdin_evec, work(2), z_zero, work(1), gemm)
1462 IF (columns(j) <= m) work(1)%local_data(:nr, j) = v(columns(j))*work(1)%local_data(:nr, j)
1466 work(3)%local_data(:n, j) = conjg(kp%lowdin_evec%local_data(orbitals(j), :n))
1469 CALL cp_cfm_transpose(kp%lowdin_evec,
'C', work(2))
1471 CALL cp_cfm_to_cfm(work(2), work(3), 1, orbitals(j), j)
1474 CALL lowdin_kp_gemm(
'N',
'C', n, n, m, work(1), work(3), z_zero, work(2), gemm)
1478 work(2)%local_data(i, j) = work(2)%local_data(i, j)/ &
1479 (kp%lowdin_sqrt(rows(i)) + kp%lowdin_sqrt(columns(j)))
1482 CALL lowdin_kp_gemm(
'N',
'N', n, n, n, kp%lowdin_evec, work(2), z_zero, work(1), gemm)
1483 CALL lowdin_kp_gemm(
'N',
'C', n, n, n, work(1), kp%lowdin_evec, z_zero, work(2), gemm)
1484 IF (.NOT. local)
CALL cp_cfm_transpose(work(2),
'C', work(1))
1488 value = work(2)%local_data(i, j) + conjg(work(2)%local_data(j, i))
1490 value = work(2)%local_data(i, j) + work(1)%local_data(i, j)
1492 kp%wmat(1, ispin)%local_data(i, j) = kp%wmat(1, ispin)%local_data(i, j) - real(
value, dp)
1493 IF (.NOT. real_only)
THEN
1494 kp%wmat(2, ispin)%local_data(i, j) = kp%wmat(2, ispin)%local_data(i, j) - aimag(
value)
1498 END SUBROUTINE lowdin_kp_force_matrix
1513 SUBROUTINE lowdin_kp_gemm(ta, tb, nrow, ncol, inner, a, b, beta, c, gemm)
1514 CHARACTER,
INTENT(IN) :: ta, tb
1515 INTEGER,
INTENT(IN) :: nrow, ncol, inner
1516 TYPE(cp_cfm_type),
INTENT(IN) :: a, b
1517 COMPLEX(KIND=dp),
INTENT(IN) :: beta
1518 TYPE(cp_cfm_type),
INTENT(INOUT) :: c
1519 TYPE(local_gemm_ctxt_type),
INTENT(INOUT) :: gemm
1521 IF (product(c%matrix_struct%context%num_pe) == 1)
THEN
1522 CALL gemm%gemm(ta, tb, nrow, ncol, inner, z_one, &
1523 a%local_data,
SIZE(a%local_data, 1), b%local_data,
SIZE(b%local_data, 1), &
1524 beta, c%local_data,
SIZE(c%local_data, 1))
1526 CALL parallel_gemm(ta, tb, nrow, ncol, inner, z_one, a, b, beta, c)
1528 END SUBROUTINE lowdin_kp_gemm
1560 SUBROUTINE mulliken(qs_env, orthonormal_basis, matrix_h, should_output, &
1561 output_unit, print_level)
1563 TYPE(qs_environment_type),
POINTER :: qs_env
1564 LOGICAL,
INTENT(IN) :: orthonormal_basis
1565 TYPE(dbcsr_p_type),
DIMENSION(:, :),
OPTIONAL, &
1567 LOGICAL,
INTENT(IN) :: should_output
1568 INTEGER,
INTENT(IN) :: output_unit, print_level
1570 CHARACTER(LEN=*),
PARAMETER :: routinen =
'mulliken'
1572 CHARACTER(LEN=10) :: spin_info
1573 CHARACTER(LEN=6),
ALLOCATABLE,
DIMENSION(:) :: symbol
1574 CHARACTER(LEN=default_string_length) :: atomic_kind_name
1575 INTEGER :: atom_a, handle, i, i0, iatom, ic, ikind, iorb, isb, iset, isgf, ishell, ispin, j, &
1576 jsb, jset, jsgf, jshell, lu, m, max_scf, n, natom, natom_of_kind, nimg, nkind, norb, nsb, &
1577 nsbsize, nset, nsgf_kind, nspin
1578 INTEGER,
DIMENSION(1) :: iloc
1579 INTEGER,
DIMENSION(:),
POINTER :: atom_list, nshell, orbitals
1580 INTEGER,
DIMENSION(:, :),
POINTER :: first_sgf, l, last_sgf
1581 LOGICAL :: debug, dft_plus_u_atom, found, &
1582 just_energy, occupation_enforced, smear
1583 LOGICAL,
ALLOCATABLE,
DIMENSION(:) :: is_plus_u_kind, orb_occ
1584 REAL(kind=dp) :: eps_scf, eps_u_ramping, fspin, occ, trq, &
1585 trq2, u_minus_j, u_minus_j_target, &
1587 REAL(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: q_eigval
1588 REAL(kind=dp),
ALLOCATABLE,
DIMENSION(:, :) :: q_eigvec, q_matrix, q_work
1589 REAL(kind=dp),
DIMENSION(:),
POINTER :: nelec
1590 REAL(kind=dp),
DIMENSION(:, :),
POINTER :: h_block, p_block, q_block, s_block, &
1592 TYPE(atomic_kind_type),
DIMENSION(:),
POINTER :: atomic_kind_set
1593 TYPE(atomic_kind_type),
POINTER :: kind_a
1594 TYPE(dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_p, matrix_s
1595 TYPE(dbcsr_type),
POINTER :: sm_h, sm_p, sm_q, sm_s, sm_v
1596 TYPE(dft_control_type),
POINTER :: dft_control
1597 TYPE(gto_basis_set_type),
POINTER :: orb_basis_set
1598 TYPE(mp_para_env_type),
POINTER :: para_env
1599 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
1600 TYPE(qs_energy_type),
POINTER :: energy
1601 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
1602 TYPE(qs_rho_type),
POINTER :: rho
1604 CALL timeset(routinen, handle)
1609 NULLIFY (atomic_kind_set)
1610 NULLIFY (qs_kind_set)
1611 NULLIFY (dft_control)
1621 NULLIFY (orb_basis_set)
1623 NULLIFY (particle_set)
1639 occupation_enforced = .false.
1641 CALL get_qs_env(qs_env=qs_env, &
1642 atomic_kind_set=atomic_kind_set, &
1643 qs_kind_set=qs_kind_set, &
1644 dft_control=dft_control, &
1646 particle_set=particle_set, &
1650 cpassert(
ASSOCIATED(atomic_kind_set))
1651 cpassert(
ASSOCIATED(dft_control))
1652 cpassert(
ASSOCIATED(energy))
1653 cpassert(
ASSOCIATED(particle_set))
1654 cpassert(
ASSOCIATED(rho))
1656 IF (orthonormal_basis)
THEN
1660 CALL get_qs_env(qs_env=qs_env, &
1661 matrix_s_kp=matrix_s)
1662 cpassert(
ASSOCIATED(matrix_s))
1664 nimg = dft_control%nimages
1668 CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
1670 energy%dft_plus_u = 0.0_dp
1672 nspin = dft_control%nspins
1674 IF (nspin == 2)
THEN
1683 CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, &
1686 nkind =
SIZE(atomic_kind_set)
1688 ALLOCATE (is_plus_u_kind(nkind))
1689 is_plus_u_kind(:) = .false.
1691 IF (
PRESENT(matrix_h))
THEN
1692 just_energy = .false.
1694 just_energy = .true.
1702 IF (.NOT. orthonormal_basis)
THEN
1703 sm_s => matrix_s(1, ic)%matrix
1706 IF (
PRESENT(matrix_h))
THEN
1708 sm_h => matrix_h(ispin, ic)%matrix
1715 sm_p => matrix_p(ispin, ic)%matrix
1717 IF (.NOT.
ASSOCIATED(sm_q))
THEN
1719 CALL dbcsr_get_block_diag(sm_p, sm_q)
1721 CALL dbcsr_set(sm_q, 0.0_dp)
1723 IF (.NOT.
ASSOCIATED(sm_v))
THEN
1725 CALL dbcsr_get_block_diag(sm_p, sm_v)
1727 CALL dbcsr_set(sm_v, 0.0_dp)
1731 CALL dbcsr_get_block_p(matrix=sm_p, &
1737 IF (.NOT.
ASSOCIATED(p_block)) cycle
1739 CALL dbcsr_get_block_p(matrix=sm_q, &
1744 cpassert(
ASSOCIATED(q_block))
1746 IF (orthonormal_basis)
THEN
1748 DO isgf = 1,
SIZE(q_block, 1)
1749 q_block(isgf, isgf) = p_block(isgf, isgf)
1752 CALL dbcsr_get_block_p(matrix=sm_s, &
1757 cpassert(
ASSOCIATED(s_block))
1759 DO jsgf = 1,
SIZE(p_block, 2)
1760 DO isgf = 1,
SIZE(p_block, 1)
1761 q_block(isgf, jsgf) = p_block(isgf, jsgf)*s_block(isgf, jsgf)
1781 CALL get_atomic_kind(atomic_kind_set(ikind), &
1782 atom_list=atom_list, &
1783 name=atomic_kind_name, &
1784 natom=natom_of_kind)
1786 CALL get_qs_kind(qs_kind_set(ikind), &
1787 dft_plus_u_atom=dft_plus_u_atom, &
1788 l_of_dft_plus_u=lu, &
1790 basis_set=orb_basis_set, &
1791 u_minus_j=u_minus_j, &
1792 u_minus_j_target=u_minus_j_target, &
1793 u_ramping=u_ramping, &
1794 eps_u_ramping=eps_u_ramping, &
1796 orbitals=orbitals, &
1803 IF (.NOT.
ASSOCIATED(orb_basis_set)) cycle
1804 IF (.NOT. dft_plus_u_atom) cycle
1809 IF ((ispin == 1) .AND. (u_ramping > 0.0_dp))
THEN
1810 IF (qs_env%scf_env%iter_delta <= eps_u_ramping)
THEN
1811 u_minus_j = min(u_minus_j + u_ramping, u_minus_j_target)
1812 CALL set_qs_kind(qs_kind_set(ikind), u_minus_j=u_minus_j)
1814 IF (should_output .AND. (output_unit > 0))
THEN
1815 WRITE (unit=output_unit, fmt=
"(T3,A,3X,A,F0.3,A)") &
1816 "Kind name: "//trim(adjustl(atomic_kind_name)), &
1817 "U(eff) = ", u_minus_j*evolt,
" eV"
1821 IF (u_minus_j == 0.0_dp) cycle
1823 is_plus_u_kind(ikind) = .true.
1827 CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
1828 first_sgf=first_sgf, &
1830 last_sgf=last_sgf, &
1838 DO ishell = 1, nshell(iset)
1839 IF (l(ishell, iset) == lu) nsb = nsb + 1
1843 nsbsize = (2*lu + 1)
1846 ALLOCATE (q_matrix(n, n))
1847 q_matrix(:, :) = 0.0_dp
1851 IF (should_output .AND. (print_level > low_print_level))
THEN
1852 IF (output_unit > 0)
THEN
1853 ALLOCATE (symbol(nsbsize))
1855 symbol(lu + m + 1) = sgf_symbol(0, lu, m)
1858 WRITE (unit=spin_info, fmt=
"(A8,I2)")
" of spin", ispin
1862 WRITE (unit=output_unit, fmt=
"(/,T3,A,I0,A,/,/,T5,A,10(2X,A6))") &
1863 "DFT+U occupations"//trim(spin_info)//
" for the atoms of atomic kind ", ikind, &
1864 ": "//trim(atomic_kind_name), &
1865 "Atom Shell ", (adjustr(symbol(i)), i=1, nsbsize),
" Trace"
1872 DO iatom = 1, natom_of_kind
1874 atom_a = atom_list(iatom)
1876 q_matrix(:, :) = 0.0_dp
1880 CALL dbcsr_get_block_p(matrix=sm_q, &
1888 IF (
ASSOCIATED(q_block))
THEN
1892 DO ishell = 1, nshell(iset)
1893 IF (l(ishell, iset) /= lu) cycle
1894 DO isgf = first_sgf(ishell, iset), last_sgf(ishell, iset)
1898 DO jshell = 1, nshell(jset)
1899 IF (l(jshell, jset) /= lu) cycle
1900 DO jsgf = first_sgf(jshell, jset), last_sgf(jshell, jset)
1902 q_matrix(i, j) = q_block(isgf, jsgf)
1912 IF (
ASSOCIATED(orbitals))
THEN
1913 IF ((qs_env%scf_env%iter_delta >= eps_scf) .OR. &
1914 ((qs_env%scf_env%outer_scf%iter_count == 0) .AND. &
1915 (qs_env%scf_env%iter_count <= max_scf)))
THEN
1916 ALLOCATE (orb_occ(nsbsize))
1917 ALLOCATE (q_eigval(n))
1918 q_eigval(:) = 0.0_dp
1919 ALLOCATE (q_eigvec(n, n))
1920 q_eigvec(:, :) = 0.0_dp
1921 norb =
SIZE(orbitals)
1922 CALL jacobi(q_matrix, q_eigval, q_eigvec)
1923 q_matrix(:, :) = 0.0_dp
1924 IF (nelec(ispin) >= 0.5_dp)
THEN
1925 trq = nelec(ispin)/sum(q_eigval(1:n))
1926 q_eigval(1:n) = trq*q_eigval(1:n)
1930 DO i = (isb - 1)*nsbsize + 1, isb*nsbsize
1931 trq = trq + q_eigval(i)
1934 occ = trq/real(norb, kind=dp)
1938 orb_occ(:) = .false.
1939 iloc = maxloc(q_eigvec(:, isb*nsbsize))
1940 jsb = int((iloc(1) - 1)/nsbsize) + 1
1942 i0 = (jsb - 1)*nsbsize + 1
1944 DO j = i0, jsb*nsbsize
1948 IF (.NOT. orb_occ(lu + m + 1))
THEN
1950 orb_occ(lu + m + 1) = .true.
1954 iorb = i0 + lu + orbitals(i)
1955 orb_occ(lu + orbitals(i) + 1) = .true.
1957 cpassert(iorb /= -1000)
1958 iloc = maxloc(q_eigvec(iorb, :))
1959 q_eigval(iloc(1)) = min(occ, trq)
1960 q_matrix(:, iloc(1)) = q_eigval(iloc(1))*q_eigvec(:, iloc(1))
1961 trq = trq - q_eigval(iloc(1))
1964 q_matrix(:, :) = matmul(q_matrix, transpose(q_eigvec))
1965 DEALLOCATE (orb_occ)
1966 DEALLOCATE (q_eigval)
1967 DEALLOCATE (q_eigvec)
1968 occupation_enforced = .true.
1976 trq = trq + q_matrix(i, i)
1978 trq2 = trq2 + q_matrix(i, j)*q_matrix(j, i)
1983 trq2 = fspin*fspin*trq2
1987 energy%dft_plus_u = energy%dft_plus_u + 0.5_dp*u_minus_j*(trq - trq2)/fspin
1991 IF (.NOT. just_energy)
THEN
1993 CALL dbcsr_get_block_p(matrix=sm_v, &
1998 cpassert(
ASSOCIATED(v_block))
2002 DO ishell = 1, nshell(iset)
2003 IF (l(ishell, iset) /= lu) cycle
2004 DO isgf = first_sgf(ishell, iset), last_sgf(ishell, iset)
2008 DO jshell = 1, nshell(jset)
2009 IF (l(jshell, jset) /= lu) cycle
2010 DO jsgf = first_sgf(jshell, jset), last_sgf(jshell, jset)
2012 IF (isgf == jsgf)
THEN
2013 v_block(isgf, isgf) = u_minus_j*(0.5_dp - fspin*q_matrix(i, i))
2015 v_block(isgf, jsgf) = -u_minus_j*fspin*q_matrix(j, i)
2030 IF (should_output .AND. (print_level > low_print_level))
THEN
2031 CALL para_env%sum(q_matrix)
2032 IF (output_unit > 0)
THEN
2033 ALLOCATE (q_work(nsb, nsbsize))
2034 q_work(:, :) = 0.0_dp
2037 DO i = (isb - 1)*nsbsize + 1, isb*nsbsize
2039 q_work(isb, j) = q_matrix(i, i)
2043 WRITE (unit=output_unit, fmt=
"(T3,I6,2X,I6,2X,10F8.3)") &
2044 atom_a, isb, q_work(isb, :), sum(q_work(isb, :))
2046 WRITE (unit=output_unit, fmt=
"(T12,A,2X,10F8.3)") &
2047 "Total", (sum(q_work(:, i)), i=1, nsbsize), sum(q_work)
2048 WRITE (unit=output_unit, fmt=
"(A)")
""
2052 WRITE (unit=output_unit, fmt=
"(T9,70I10)") (i, i=1, n)
2054 WRITE (unit=output_unit, fmt=
"(T3,I6,70F10.6)") i, q_matrix(i, :)
2057 ALLOCATE (q_eigval(n))
2058 q_eigval(:) = 0.0_dp
2059 ALLOCATE (q_eigvec(n, n))
2060 q_eigvec(:, :) = 0.0_dp
2061 CALL jacobi(q_matrix, q_eigval, q_eigvec)
2062 WRITE (unit=output_unit, fmt=
"(/,T9,70I10)") (i, i=1, n)
2063 WRITE (unit=output_unit, fmt=
"(T9,71F10.6)") (q_eigval(i), i=1, n), &
2066 WRITE (unit=output_unit, fmt=
"(T3,I6,70F10.6)") i, q_eigvec(i, :)
2068 DEALLOCATE (q_eigval)
2069 DEALLOCATE (q_eigvec)
2074 ALLOCATE (q_work(nsgf_kind, nsgf_kind))
2075 q_work(:, :) = 0.0_dp
2076 IF (
ASSOCIATED(q_block)) q_work(:, :) = q_block(:, :)
2077 CALL para_env%sum(q_work)
2078 IF (output_unit > 0)
THEN
2079 norb =
SIZE(q_work, 1)
2080 WRITE (unit=output_unit, fmt=
"(/,T9,200I10)") (i, i=1, norb)
2082 WRITE (unit=output_unit, fmt=
"(T3,I6,200F10.6)") i, q_work(i, :)
2084 ALLOCATE (q_eigval(norb))
2085 q_eigval(:) = 0.0_dp
2086 ALLOCATE (q_eigvec(norb, norb))
2087 q_eigvec(:, :) = 0.0_dp
2088 CALL jacobi(q_work, q_eigval, q_eigvec)
2089 WRITE (unit=output_unit, fmt=
"(/,T9,200I10)") (i, i=1, norb)
2090 WRITE (unit=output_unit, fmt=
"(T9,201F10.6)") (q_eigval(i), i=1, norb), &
2091 sum(q_eigval(1:norb))
2093 WRITE (unit=output_unit, fmt=
"(T3,I6,200F10.6)") i, q_eigvec(i, :)
2095 DEALLOCATE (q_eigval)
2096 DEALLOCATE (q_eigvec)
2104 IF (
ALLOCATED(q_matrix))
THEN
2105 DEALLOCATE (q_matrix)
2112 IF (
ASSOCIATED(sm_h))
THEN
2116 IF (.NOT. is_plus_u_kind(ikind)) cycle
2118 kind_a => atomic_kind_set(ikind)
2120 CALL get_atomic_kind(atomic_kind=kind_a, &
2121 atom_list=atom_list, &
2122 natom=natom_of_kind)
2124 DO iatom = 1, natom_of_kind
2126 atom_a = atom_list(iatom)
2128 CALL dbcsr_get_block_p(matrix=sm_h, &
2134 IF (.NOT.
ASSOCIATED(h_block)) cycle
2136 CALL dbcsr_get_block_p(matrix=sm_v, &
2141 cpassert(
ASSOCIATED(v_block))
2143 IF (orthonormal_basis)
THEN
2144 DO isgf = 1,
SIZE(h_block, 1)
2145 h_block(isgf, isgf) = h_block(isgf, isgf) + v_block(isgf, isgf)
2148 CALL dbcsr_get_block_p(matrix=sm_s, &
2153 cpassert(
ASSOCIATED(s_block))
2154 DO jsgf = 1,
SIZE(h_block, 2)
2155 DO isgf = 1,
SIZE(h_block, 1)
2156 h_block(isgf, jsgf) = h_block(isgf, jsgf) + v_block(isgf, jsgf)*s_block(isgf, jsgf)
2173 CALL para_env%sum(energy%dft_plus_u)
2175 IF (energy%dft_plus_u < 0.0_dp)
THEN
2176 IF (.NOT. occupation_enforced)
THEN
2177 CALL cp_warn(__location__, &
2178 "DFT+U energy contribution is negative possibly due "// &
2179 "to unphysical Mulliken charges!")
2183 CALL dbcsr_deallocate_matrix(sm_q)
2184 CALL dbcsr_deallocate_matrix(sm_v)
2186 CALL timestop(handle)
2226 SUBROUTINE mulliken_charges(qs_env, orthonormal_basis, matrix_h, matrix_w, &
2227 should_output, output_unit, print_level)
2229 TYPE(qs_environment_type),
POINTER :: qs_env
2230 LOGICAL,
INTENT(IN) :: orthonormal_basis
2231 TYPE(dbcsr_p_type),
DIMENSION(:, :),
OPTIONAL, &
2232 POINTER :: matrix_h, matrix_w
2233 LOGICAL,
INTENT(IN) :: should_output
2234 INTEGER,
INTENT(IN) :: output_unit, print_level
2236 CHARACTER(LEN=*),
PARAMETER :: routinen =
'mulliken_charges'
2238 CHARACTER(LEN=10) :: spin_info
2239 CHARACTER(LEN=6),
ALLOCATABLE,
DIMENSION(:) :: symbol
2240 CHARACTER(LEN=default_string_length) :: atomic_kind_name
2241 INTEGER :: atom_a, handle, i, iatom, ic, ikind, isb, iset, isgf, ishell, ispin, jatom, jsgf, &
2242 lu, m, natom, natom_of_kind, nimg, nkind, nsb, nset, nsgf, nspin, sgf
2243 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: first_sgf_atom
2244 INTEGER,
DIMENSION(:),
POINTER :: atom_list, nshell
2245 INTEGER,
DIMENSION(:, :),
POINTER :: first_sgf, l, last_sgf
2246 LOGICAL :: dft_plus_u_atom, found, just_energy
2247 REAL(kind=dp) :: eps_u_ramping, fspin, q, u_minus_j, &
2248 u_minus_j_target, u_ramping, v
2249 REAL(kind=dp),
ALLOCATABLE,
DIMENSION(:) :: dedq, trps
2250 REAL(kind=dp),
ALLOCATABLE,
DIMENSION(:, :) :: q_ii
2251 REAL(kind=dp),
DIMENSION(:, :),
POINTER :: h_block, p_block, s_block, w_block
2252 TYPE(atomic_kind_type),
DIMENSION(:),
POINTER :: atomic_kind_set
2253 TYPE(dbcsr_iterator_type) :: iter
2254 TYPE(dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrix_p, matrix_s
2255 TYPE(dbcsr_type),
POINTER :: sm_h, sm_p, sm_s, sm_w
2256 TYPE(dft_control_type),
POINTER :: dft_control
2257 TYPE(gto_basis_set_type),
POINTER :: orb_basis_set
2258 TYPE(mp_para_env_type),
POINTER :: para_env
2259 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
2260 TYPE(qs_energy_type),
POINTER :: energy
2261 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2262 TYPE(qs_rho_type),
POINTER :: rho
2264 CALL timeset(routinen, handle)
2267 NULLIFY (atomic_kind_set)
2268 NULLIFY (qs_kind_set)
2269 NULLIFY (dft_control)
2278 NULLIFY (orb_basis_set)
2280 NULLIFY (particle_set)
2289 CALL get_qs_env(qs_env=qs_env, &
2290 atomic_kind_set=atomic_kind_set, &
2291 qs_kind_set=qs_kind_set, &
2292 dft_control=dft_control, &
2294 particle_set=particle_set, &
2298 cpassert(
ASSOCIATED(atomic_kind_set))
2299 cpassert(
ASSOCIATED(dft_control))
2300 cpassert(
ASSOCIATED(energy))
2301 cpassert(
ASSOCIATED(particle_set))
2302 cpassert(
ASSOCIATED(rho))
2304 IF (orthonormal_basis)
THEN
2308 CALL get_qs_env(qs_env=qs_env, &
2309 matrix_s_kp=matrix_s)
2310 cpassert(
ASSOCIATED(matrix_s))
2315 CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
2317 energy%dft_plus_u = 0.0_dp
2319 nspin = dft_control%nspins
2320 nimg = dft_control%nimages
2322 IF (nspin == 2)
THEN
2331 CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, natom=natom)
2332 CALL get_qs_kind_set(qs_kind_set, nsgf=nsgf)
2334 nkind =
SIZE(atomic_kind_set)
2336 ALLOCATE (first_sgf_atom(natom))
2337 first_sgf_atom(:) = 0
2339 CALL get_particle_set(particle_set, qs_kind_set, &
2340 first_sgf=first_sgf_atom)
2342 ALLOCATE (trps(nsgf))
2345 IF (
PRESENT(matrix_h) .OR.
PRESENT(matrix_w))
THEN
2346 ALLOCATE (dedq(nsgf))
2347 just_energy = .false.
2349 just_energy = .true.
2356 IF (.NOT. just_energy) dedq(:) = 0.0_dp
2363 IF (orthonormal_basis)
THEN
2366 sm_s => matrix_s(1, ic)%matrix
2368 sm_p => matrix_p(ispin, ic)%matrix
2370 CALL dbcsr_iterator_start(iter, sm_p)
2372 DO WHILE (dbcsr_iterator_blocks_left(iter))
2374 CALL dbcsr_iterator_next_block(iter, iatom, jatom, p_block)
2376 IF (orthonormal_basis)
THEN
2378 IF (iatom /= jatom) cycle
2380 IF (
ASSOCIATED(p_block))
THEN
2381 sgf = first_sgf_atom(iatom)
2382 DO isgf = 1,
SIZE(p_block, 1)
2383 trps(sgf) = trps(sgf) + p_block(isgf, isgf)
2390 CALL dbcsr_get_block_p(matrix=sm_s, &
2395 cpassert(
ASSOCIATED(s_block))
2397 sgf = first_sgf_atom(jatom)
2398 DO jsgf = 1,
SIZE(p_block, 2)
2399 DO isgf = 1,
SIZE(p_block, 1)
2400 trps(sgf) = trps(sgf) + p_block(isgf, jsgf)*s_block(isgf, jsgf)
2405 IF (iatom /= jatom)
THEN
2406 sgf = first_sgf_atom(iatom)
2407 DO isgf = 1,
SIZE(p_block, 1)
2408 DO jsgf = 1,
SIZE(p_block, 2)
2409 trps(sgf) = trps(sgf) + p_block(isgf, jsgf)*s_block(isgf, jsgf)
2419 CALL dbcsr_iterator_stop(iter)
2423 CALL para_env%sum(trps)
2439 CALL get_atomic_kind(atomic_kind_set(ikind), &
2440 atom_list=atom_list, &
2441 name=atomic_kind_name, &
2442 natom=natom_of_kind)
2444 CALL get_qs_kind(qs_kind_set(ikind), &
2445 dft_plus_u_atom=dft_plus_u_atom, &
2446 l_of_dft_plus_u=lu, &
2447 basis_set=orb_basis_set, &
2448 u_minus_j=u_minus_j, &
2449 u_minus_j_target=u_minus_j_target, &
2450 u_ramping=u_ramping, &
2451 eps_u_ramping=eps_u_ramping)
2455 IF (.NOT.
ASSOCIATED(orb_basis_set)) cycle
2456 IF (.NOT. dft_plus_u_atom) cycle
2461 IF ((ispin == 1) .AND. (u_ramping > 0.0_dp))
THEN
2462 IF (qs_env%scf_env%iter_delta <= eps_u_ramping)
THEN
2463 u_minus_j = min(u_minus_j + u_ramping, u_minus_j_target)
2464 CALL set_qs_kind(qs_kind_set(ikind), u_minus_j=u_minus_j)
2466 IF (should_output .AND. (output_unit > 0))
THEN
2467 WRITE (unit=output_unit, fmt=
"(T3,A,3X,A,F0.3,A)") &
2468 "Kind name: "//trim(adjustl(atomic_kind_name)), &
2469 "U(eff) = ", u_minus_j*evolt,
" eV"
2473 IF (u_minus_j == 0.0_dp) cycle
2477 CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
2478 first_sgf=first_sgf, &
2480 last_sgf=last_sgf, &
2488 DO ishell = 1, nshell(iset)
2489 IF (l(ishell, iset) == lu) nsb = nsb + 1
2493 ALLOCATE (q_ii(nsb, 2*lu + 1))
2497 IF (should_output .AND. (print_level > low_print_level))
THEN
2498 IF (output_unit > 0)
THEN
2499 ALLOCATE (symbol(2*lu + 1))
2501 symbol(lu + m + 1) = sgf_symbol(0, lu, m)
2504 WRITE (unit=spin_info, fmt=
"(A8,I2)")
" of spin", ispin
2508 WRITE (unit=output_unit, fmt=
"(/,T3,A,I0,A,/,/,T5,A,10(2X,A6))") &
2509 "DFT+U occupations"//trim(spin_info)//
" for the atoms of atomic kind ", ikind, &
2510 ": "//trim(atomic_kind_name), &
2511 "Atom Shell ", (adjustr(symbol(i)), i=1, 2*lu + 1),
" Trace"
2518 DO iatom = 1, natom_of_kind
2520 atom_a = atom_list(iatom)
2526 CALL dbcsr_get_block_p(matrix=sm_p, &
2534 IF (
ASSOCIATED(p_block))
THEN
2536 sgf = first_sgf_atom(atom_a)
2540 DO ishell = 1, nshell(iset)
2541 IF (l(ishell, iset) == lu)
THEN
2544 DO isgf = first_sgf(ishell, iset), last_sgf(ishell, iset)
2548 energy%dft_plus_u = energy%dft_plus_u + &
2549 0.5_dp*u_minus_j*(q - q**2)/fspin
2550 IF (.NOT. just_energy)
THEN
2551 dedq(sgf) = dedq(sgf) + u_minus_j*(0.5_dp - q)
2556 sgf = sgf + last_sgf(ishell, iset) - first_sgf(ishell, iset) + 1
2565 IF (should_output .AND. (print_level > low_print_level))
THEN
2566 CALL para_env%sum(q_ii)
2567 IF (output_unit > 0)
THEN
2569 WRITE (unit=output_unit, fmt=
"(T3,I6,2X,I6,2X,10F8.3)") &
2570 atom_a, isb, q_ii(isb, :), sum(q_ii(isb, :))
2572 WRITE (unit=output_unit, fmt=
"(T12,A,2X,10F8.3)") &
2573 "Total", (sum(q_ii(:, i)), i=1, 2*lu + 1), sum(q_ii)
2574 WRITE (unit=output_unit, fmt=
"(A)")
""
2580 IF (
ALLOCATED(q_ii))
THEN
2586 IF (.NOT. just_energy)
THEN
2587 CALL para_env%sum(dedq)
2592 IF (
PRESENT(matrix_h))
THEN
2595 IF (orthonormal_basis)
THEN
2598 sm_s => matrix_s(1, ic)%matrix
2600 sm_h => matrix_h(ispin, ic)%matrix
2602 CALL dbcsr_iterator_start(iter, sm_h)
2604 DO WHILE (dbcsr_iterator_blocks_left(iter))
2606 CALL dbcsr_iterator_next_block(iter, iatom, jatom, h_block)
2608 IF (orthonormal_basis)
THEN
2610 IF (iatom /= jatom) cycle
2612 IF (
ASSOCIATED(h_block))
THEN
2613 sgf = first_sgf_atom(iatom)
2614 DO isgf = 1,
SIZE(h_block, 1)
2615 h_block(isgf, isgf) = h_block(isgf, isgf) + dedq(sgf)
2624 CALL dbcsr_get_block_p(matrix=sm_s, &
2629 cpassert(
ASSOCIATED(s_block))
2633 sgf = first_sgf_atom(iatom)
2635 DO isgf = 1,
SIZE(h_block, 1)
2636 IF (dedq(sgf) /= 0.0_dp)
THEN
2637 v = 0.5_dp*dedq(sgf)
2638 DO jsgf = 1,
SIZE(h_block, 2)
2639 h_block(isgf, jsgf) = h_block(isgf, jsgf) + v*s_block(isgf, jsgf)
2645 sgf = first_sgf_atom(jatom)
2647 DO jsgf = 1,
SIZE(h_block, 2)
2648 IF (dedq(sgf) /= 0.0_dp)
THEN
2649 v = 0.5_dp*dedq(sgf)
2650 DO isgf = 1,
SIZE(h_block, 1)
2651 h_block(isgf, jsgf) = h_block(isgf, jsgf) + v*s_block(isgf, jsgf)
2661 CALL dbcsr_iterator_stop(iter)
2671 IF (
PRESENT(matrix_w) .AND. (.NOT. orthonormal_basis))
THEN
2674 sm_s => matrix_s(1, ic)%matrix
2675 sm_p => matrix_p(ispin, ic)%matrix
2676 sm_w => matrix_w(ispin, ic)%matrix
2678 CALL dbcsr_iterator_start(iter, sm_p)
2680 DO WHILE (dbcsr_iterator_blocks_left(iter))
2682 CALL dbcsr_iterator_next_block(iter, iatom, jatom, p_block)
2686 IF (iatom == jatom) cycle
2690 CALL dbcsr_get_block_p(matrix=sm_w, &
2695 cpassert(
ASSOCIATED(w_block))
2699 sgf = first_sgf_atom(iatom)
2701 DO isgf = 1,
SIZE(w_block, 1)
2702 IF (dedq(sgf) /= 0.0_dp)
THEN
2703 v = -0.5_dp*dedq(sgf)
2704 DO jsgf = 1,
SIZE(w_block, 2)
2705 w_block(isgf, jsgf) = w_block(isgf, jsgf) + v*p_block(isgf, jsgf)
2711 sgf = first_sgf_atom(jatom)
2713 DO jsgf = 1,
SIZE(w_block, 2)
2714 IF (dedq(sgf) /= 0.0_dp)
THEN
2715 v = -0.5_dp*dedq(sgf)
2716 DO isgf = 1,
SIZE(w_block, 1)
2717 w_block(isgf, jsgf) = w_block(isgf, jsgf) + v*p_block(isgf, jsgf)
2725 CALL dbcsr_iterator_stop(iter)
2735 CALL para_env%sum(energy%dft_plus_u)
2737 IF (energy%dft_plus_u < 0.0_dp)
THEN
2738 CALL cp_warn(__location__, &
2739 "DFT+U energy contribution is negative possibly due "// &
2740 "to unphysical Mulliken charges!")
2745 IF (
ALLOCATED(first_sgf_atom))
THEN
2746 DEALLOCATE (first_sgf_atom)
2749 IF (
ALLOCATED(trps))
THEN
2753 IF (
ALLOCATED(dedq))
THEN
2757 CALL timestop(handle)
2759 END SUBROUTINE mulliken_charges
2773 SUBROUTINE tensorial(qs_env, matrix_h, matrix_w, should_output, output_unit, print_level)
2775 TYPE(qs_environment_type),
POINTER :: qs_env
2776 TYPE(dbcsr_p_type),
DIMENSION(:, :),
OPTIONAL, &
2777 POINTER :: matrix_h, matrix_w
2778 LOGICAL,
INTENT(IN) :: should_output
2779 INTEGER,
INTENT(IN) :: output_unit, print_level
2781 CHARACTER(LEN=*),
PARAMETER :: routinen =
'tensorial'
2783 CHARACTER(LEN=10) :: spin_info
2784 CHARACTER(LEN=6),
ALLOCATABLE :: symbol(:)
2785 CHARACTER(LEN=default_string_length) :: atomic_kind_name
2786 INTEGER :: atom_a, atom_aa, handle, i, i0, iatom, ikind, iorb, isb, iset, isgf, ishell, &
2787 ispin, j, jatom, jj, jkind, jsb, jset, jsgf, jshell, katom, lu, m, matom_of_kind, &
2788 max_scf, n, natom, natom_of_kind, nkind, norb, nsb, nsbsize, nset, nsgf, nsgf_kind, &
2789 nsgf_kind2, nspin, timevalues(8)
2790 INTEGER,
ALLOCATABLE :: first_sgf_atom(:)
2791 INTEGER,
DIMENSION(1) :: iloc
2792 INTEGER,
DIMENSION(:),
POINTER :: atom_list, atom_list2, nshell, orbitals
2793 INTEGER,
DIMENSION(:, :),
POINTER :: first_sgf, l, last_sgf
2794 LOGICAL :: debug, dft_plus_u_atom, found, &
2796 LOGICAL,
ALLOCATABLE :: orb_occ(:)
2797 REAL(kind=dp) :: eps_scf, eps_u_ramping, fspin, hund_j, occ, perturbation_strength, &
2798 some_real, trq, trq2, trqxq_hund_j, u_minus_j, u_minus_j_target, u_ramping
2799 REAL(kind=dp),
ALLOCATABLE :: a(:), q_a_matrix(:, :), q_b_matrix(:, :), q_eigval(:), &
2800 q_eigvec(:, :), q_work(:, :), s_inv_matrix(:, :), s_matrix(:, :), tmp_matrix1(:, :), &
2801 tmp_matrix2(:, :), tmp_matrix3(:, :), v_matrix(:, :), vhxc_matrix(:, :)
2804 REAL(kind=dp),
ALLOCATABLE :: matrix(:, :, :)
2807 REAL(kind=dp),
ALLOCATABLE :: matrix(:, :, :, :)
2809 TYPE(block3d),
ALLOCATABLE :: a_matrix(:, :), d_matrix(:, :), &
2810 e_matrix(:, :), i_matrix(:, :), &
2812 TYPE(block4d),
ALLOCATABLE :: dd_matrix(:, :), ee_matrix(:, :), &
2814 REAL(kind=dp),
DIMENSION(:),
POINTER :: ao_coef
2815 REAL(kind=dp),
DIMENSION(:, :),
POINTER :: a_block, d_block, e_block, f_block, &
2816 i_block, j_block, q_a_block, q_b_block, &
2817 s_block, tmp_block, v_block, vhxc_block
2819 TYPE(atomic_kind_type),
DIMENSION(:),
POINTER :: atomic_kind_set
2820 TYPE(mp_para_env_type),
POINTER :: para_env
2821 TYPE(dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_p, matrix_s, matrix_vhxc
2822 TYPE(dbcsr_p_type),
DIMENSION(:, :),
POINTER :: matrixkp_s
2823 TYPE(dbcsr_type),
POINTER :: sm_a, sm_b, sm_c, sm_d, sm_e, sm_f, &
2824 sm_h, sm_i, sm_j, sm_k, sm_q_a, sm_q_b, &
2825 sm_s, sm_v, sm_w, sm_mid, sm_vhxc, sm_p
2826 TYPE(dbcsr_iterator_type) :: iter
2827 TYPE(dft_control_type),
POINTER :: dft_control
2828 TYPE(gto_basis_set_type),
POINTER :: orb_basis_set
2829 TYPE(particle_type),
DIMENSION(:),
POINTER :: particle_set
2830 TYPE(qs_energy_type),
POINTER :: energy
2831 TYPE(qs_force_type),
DIMENSION(:),
POINTER :: force
2832 TYPE(qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
2833 TYPE(qs_rho_type),
POINTER :: rho
2834 TYPE(qs_scf_env_type),
POINTER :: scf_env
2836 CALL timeset(routinen, handle)
2844 NULLIFY (atom_list2)
2845 NULLIFY (atomic_kind_set)
2846 NULLIFY (qs_kind_set)
2847 NULLIFY (dft_control)
2853 NULLIFY (matrix_vhxc)
2857 NULLIFY (orb_basis_set)
2860 NULLIFY (particle_set)
2863 NULLIFY (vhxc_block)
2894 CALL get_qs_env(qs_env=qs_env, &
2895 atomic_kind_set=atomic_kind_set, &
2896 qs_kind_set=qs_kind_set, &
2897 dft_control=dft_control, &
2899 matrix_s=matrix_s, &
2900 matrix_vhxc=matrix_vhxc, &
2901 matrix_s_kp=matrixkp_s, &
2902 particle_set=particle_set, &
2907 cpassert(
ASSOCIATED(atomic_kind_set))
2908 cpassert(
ASSOCIATED(dft_control))
2909 cpassert(
ASSOCIATED(energy))
2910 cpassert(
ASSOCIATED(matrix_s))
2911 cpassert(
ASSOCIATED(particle_set))
2912 cpassert(
ASSOCIATED(rho))
2914 sm_s => matrix_s(1)%matrix
2915 CALL qs_rho_get(rho, rho_ao=matrix_p)
2917 energy%dft_plus_u = 0.0_dp
2919 nspin = dft_control%nspins
2920 IF (dft_control%mtlr_dft_with_perturbation)
THEN
2921 IF (.NOT.
ASSOCIATED(matrix_vhxc))
THEN
2922 cpabort(
"MTLR requires the projected Hxc matrix for every spin channel.")
2924 IF (
SIZE(matrix_vhxc) /= nspin)
THEN
2925 cpabort(
"The number of projected Hxc matrices does not match the spin channels.")
2929 IF (nspin == 2)
THEN
2938 CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, natom=natom)
2939 CALL get_qs_kind_set(qs_kind_set, nsgf=nsgf)
2941 nkind =
SIZE(atomic_kind_set)
2943 ALLOCATE (first_sgf_atom(natom))
2944 first_sgf_atom(:) = 0
2946 CALL get_particle_set(particle_set, qs_kind_set, first_sgf=first_sgf_atom)
2948 IF (
PRESENT(matrix_h) .OR.
PRESENT(matrix_w))
THEN
2949 just_energy = .false.
2951 just_energy = .true.
2954 CALL dbcsr_init_p(sm_mid)
2955 CALL dbcsr_create(sm_mid, template=sm_s, matrix_type=
"N")
2960 CALL dbcsr_get_block_diag(sm_s, sm_q_a)
2963 CALL dbcsr_get_block_diag(sm_s, sm_q_b)
2965 CALL dbcsr_set(sm_q_a, 0.0_dp)
2966 CALL dbcsr_set(sm_q_b, 0.0_dp)
2972 sm_p => matrix_p(ispin)%matrix
2974 IF (nspin == 2)
THEN
2975 IF (ispin == 1)
THEN
2976 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, sm_s, sm_p, 0.0_dp, sm_mid)
2977 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, sm_mid, sm_s, 0.0_dp, sm_q_a)
2979 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, sm_s, sm_p, 0.0_dp, sm_mid)
2980 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, sm_mid, sm_s, 0.0_dp, sm_q_b)
2983 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, sm_s, sm_p, 0.0_dp, sm_mid)
2984 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, sm_mid, sm_s, 0.0_dp, sm_q_a)
2985 CALL dbcsr_copy(sm_q_b, sm_q_a)
2991 CALL dbcsr_get_block_diag(sm_s, sm_v)
2993 IF (
PRESENT(matrix_w))
THEN
2995 CALL dbcsr_init_p(sm_b)
2996 CALL dbcsr_create(sm_b, template=matrix_s(1)%matrix, matrix_type=
"N")
2998 CALL dbcsr_init_p(sm_d)
2999 CALL dbcsr_create(sm_d, template=matrix_s(1)%matrix, matrix_type=
"N")
3001 CALL dbcsr_init_p(sm_c)
3002 CALL dbcsr_create(sm_c, template=matrix_s(1)%matrix, matrix_type=
"N")
3004 CALL dbcsr_init_p(sm_e)
3005 CALL dbcsr_create(sm_e, template=matrix_s(1)%matrix, matrix_type=
"N")
3007 CALL dbcsr_init_p(sm_f)
3008 CALL dbcsr_create(sm_f, template=matrix_s(1)%matrix, matrix_type=
"N")
3010 CALL dbcsr_init_p(sm_i)
3011 CALL dbcsr_create(sm_i, template=matrix_s(1)%matrix, matrix_type=
"N")
3013 CALL dbcsr_init_p(sm_j)
3014 CALL dbcsr_create(sm_j, template=matrix_s(1)%matrix, matrix_type=
"N")
3016 CALL dbcsr_init_p(sm_k)
3017 CALL dbcsr_create(sm_k, template=matrix_s(1)%matrix, matrix_type=
"N")
3022 CALL dbcsr_get_block_diag(sm_s, sm_a)
3028 IF (
PRESENT(matrix_h))
THEN
3029 sm_h => matrix_h(ispin, 1)%matrix
3034 IF (
PRESENT(matrix_w))
THEN
3035 sm_w => matrix_w(ispin, 1)%matrix
3040 CALL dbcsr_set(sm_v, 0.0_dp)
3041 CALL dbcsr_set(sm_a, 0.0_dp)
3043 IF (dft_control%mtlr_dft_with_perturbation)
THEN
3044 IF (ispin == 1) perturbation_strength = 0.9_dp*dft_control%perturbation_strength
3045 IF (ispin == 2) perturbation_strength = 1.1_dp*dft_control%perturbation_strength
3046 IF (.NOT.
ASSOCIATED(matrix_vhxc(ispin)%matrix))
THEN
3047 cpabort(
"MTLR projected Hxc matrix is not initialized.")
3049 sm_vhxc => matrix_vhxc(ispin)%matrix
3056 CALL get_atomic_kind(atomic_kind_set(ikind), &
3057 atom_list=atom_list, &
3058 name=atomic_kind_name, &
3059 natom=natom_of_kind)
3061 CALL get_qs_kind(qs_kind_set(ikind), &
3062 dft_plus_u_atom=dft_plus_u_atom, &
3063 l_of_dft_plus_u=lu, &
3065 basis_set=orb_basis_set, &
3066 u_minus_j=u_minus_j, &
3069 u_minus_j_target=u_minus_j_target, &
3070 u_ramping=u_ramping, &
3071 eps_u_ramping=eps_u_ramping, &
3072 orbitals=orbitals, &
3077 IF (.NOT.
ASSOCIATED(orb_basis_set)) cycle
3078 IF (.NOT. dft_plus_u_atom) cycle
3080 IF (u_minus_j == 0.0_dp .AND. hund_j == 0.0_dp) cycle
3081 IF (.NOT.
ASSOCIATED(ao_coef))
THEN
3082 cpabort(
"Tensorial DFT+U requires associated ao_coef")
3085 ALLOCATE (a(
SIZE(ao_coef)))
3090 IF ((ispin == 1) .AND. (u_ramping > 0.0_dp))
THEN
3091 IF (qs_env%scf_env%iter_delta <= eps_u_ramping)
THEN
3092 u_minus_j = min(u_minus_j + u_ramping, u_minus_j_target)
3093 CALL set_qs_kind(qs_kind_set(ikind), u_minus_j=u_minus_j)
3096 IF (should_output .AND. (output_unit > 0))
THEN
3097 WRITE (unit=output_unit, fmt=
"(T3,A,3X,A,F0.3,A)") &
3098 "Kind name: "//trim(adjustl(atomic_kind_name)), &
3099 "U(eff) = ", u_minus_j*evolt,
" eV"
3103 CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
3104 first_sgf=first_sgf, &
3106 last_sgf=last_sgf, &
3111 nsbsize = (2*lu + 1)
3114 ALLOCATE (q_a_matrix(n, n))
3115 ALLOCATE (q_b_matrix(n, n))
3116 ALLOCATE (s_matrix(n, n))
3117 ALLOCATE (s_inv_matrix(n, n))
3118 ALLOCATE (v_matrix(n, n))
3120 q_a_matrix(:, :) = 0.0_dp
3121 q_b_matrix(:, :) = 0.0_dp
3122 s_matrix(:, :) = 0.0_dp
3123 s_inv_matrix(:, :) = 0.0_dp
3124 v_matrix(:, :) = 0.0_dp
3128 IF (should_output .AND. (print_level > low_print_level))
THEN
3129 IF (output_unit > 0)
THEN
3130 ALLOCATE (symbol(nsbsize))
3132 symbol(lu + m + 1) = sgf_symbol(0, lu, m)
3136 WRITE (unit=spin_info, fmt=
"(A8,I2)")
" of spin", ispin
3141 WRITE (unit=output_unit, fmt=
"(/,T3,A,I0,A,/,/,T5,A,10(2X,A6))") &
3142 "DFT+U occupations"//trim(spin_info)//
" for the atoms of atomic kind ", ikind, &
3143 ": "//trim(atomic_kind_name), &
3144 "Atom Shell ", (adjustr(symbol(i)), i=1, nsbsize),
" Trace"
3150 IF (dft_control%mtlr_dft_with_perturbation .AND. &
3151 dft_control%mtlr_ikind == ikind)
THEN
3152 dft_control%vhxc(ispin) = 0.0_dp
3153 dft_control%trq(ispin) = 0.0_dp
3154 ALLOCATE (vhxc_matrix(n, n))
3155 vhxc_matrix(:, :) = 0.0_dp
3160 DO iatom = 1, natom_of_kind
3162 atom_a = atom_list(iatom)
3164 q_a_matrix(:, :) = 0.0_dp
3165 q_b_matrix(:, :) = 0.0_dp
3166 s_matrix(:, :) = 0.0_dp
3167 s_inv_matrix(:, :) = 0.0_dp
3168 v_matrix(:, :) = 0.0_dp
3170 CALL dbcsr_get_block_p(matrix=sm_q_a, &
3176 CALL dbcsr_get_block_p(matrix=sm_q_b, &
3182 CALL dbcsr_get_block_p(matrix=sm_s, &
3188 IF (dft_control%mtlr_dft_with_perturbation .AND. &
3189 dft_control%mtlr_ikind == ikind .AND. &
3190 qs_kind_set(ikind)%dft_plus_u%lr_atom == atom_a)
THEN
3191 CALL dbcsr_get_block_p(matrix=sm_vhxc, &
3198 IF (
ASSOCIATED(q_a_block) .AND.
ASSOCIATED(q_b_block) .AND.
ASSOCIATED(s_block))
THEN
3202 DO ishell = 1, nshell(iset)
3203 IF (l(ishell, iset) /= lu) cycle
3206 DO isgf = first_sgf(ishell, iset), last_sgf(ishell, iset)
3210 DO jshell = 1, nshell(jset)
3211 IF (l(jshell, jset) /= lu) cycle
3214 DO jsgf = first_sgf(jshell, jset), last_sgf(jshell, jset)
3216 q_a_matrix(i, j) = q_a_matrix(i, j) + q_a_block(isgf, jsgf)*a(isb)*a(jsb)
3217 q_b_matrix(i, j) = q_b_matrix(i, j) + q_b_block(isgf, jsgf)*a(isb)*a(jsb)
3218 s_matrix(i, j) = s_matrix(i, j) + s_block(isgf, jsgf)*a(isb)*a(jsb)
3219 IF (
ASSOCIATED(vhxc_block) .AND. &
3220 dft_control%mtlr_dft_with_perturbation .AND. &
3221 dft_control%mtlr_ikind == ikind .AND. &
3222 qs_kind_set(ikind)%dft_plus_u%lr_atom == atom_a)
THEN
3223 vhxc_matrix(i, j) = vhxc_matrix(i, j) + vhxc_block(isgf, jsgf)*a(isb)*a(jsb)
3232 CALL invert_matrix(s_matrix, s_inv_matrix, some_real)
3234 q_a_matrix(:, :) = matmul(q_a_matrix, s_inv_matrix)
3235 q_b_matrix(:, :) = matmul(q_b_matrix, s_inv_matrix)
3237 IF (
ASSOCIATED(vhxc_block) .AND. &
3238 dft_control%mtlr_dft_with_perturbation .AND. &
3239 dft_control%mtlr_ikind == ikind .AND. &
3240 qs_kind_set(ikind)%dft_plus_u%lr_atom == atom_a)
THEN
3241 vhxc_matrix(:, :) = matmul(vhxc_matrix, s_inv_matrix)
3243 dft_control%vhxc(ispin) = dft_control%vhxc(ispin) + vhxc_matrix(i, i)
3244 IF (ispin == 1) dft_control%trq(1) = dft_control%trq(1) + q_a_matrix(i, i)
3245 IF (ispin == 2) dft_control%trq(2) = dft_control%trq(2) + q_b_matrix(i, i)
3251 IF (
ASSOCIATED(orbitals))
THEN
3252 IF ((qs_env%scf_env%iter_delta >= eps_scf) .OR. &
3253 ((qs_env%scf_env%outer_scf%iter_count == 0) .AND. &
3254 (qs_env%scf_env%iter_count <= max_scf)))
THEN
3256 ALLOCATE (orb_occ(nsbsize))
3257 ALLOCATE (q_eigval(n))
3258 ALLOCATE (q_eigvec(n, n))
3260 q_eigval(:) = 0.0_dp
3261 q_eigvec(:, :) = 0.0_dp
3262 norb =
SIZE(orbitals)
3264 IF (ispin == 1)
THEN
3265 CALL jacobi(q_a_matrix, q_eigval, q_eigvec)
3266 q_a_matrix(:, :) = 0.0_dp
3268 CALL jacobi(q_b_matrix, q_eigval, q_eigvec)
3269 q_b_matrix(:, :) = 0.0_dp
3274 DO i = (isb - 1)*nsbsize + 1, isb*nsbsize
3275 trq = trq + q_eigval(i)
3279 occ = trq/real(norb, kind=dp)
3284 orb_occ(:) = .false.
3285 iloc = maxloc(q_eigvec(:, isb*nsbsize))
3286 jsb = int((iloc(1) - 1)/nsbsize) + 1
3288 i0 = (jsb - 1)*nsbsize + 1
3291 DO j = i0, jsb*nsbsize
3295 IF (.NOT. orb_occ(lu + m + 1))
THEN
3297 orb_occ(lu + m + 1) = .true.
3301 iorb = i0 + lu + orbitals(i)
3302 orb_occ(lu + orbitals(i) + 1) = .true.
3305 cpassert(iorb /= -1000)
3307 iloc = maxloc(q_eigvec(iorb, :))
3308 q_eigval(iloc(1)) = min(occ, trq)
3310 IF (ispin == 1)
THEN
3311 q_a_matrix(:, iloc(1)) = q_eigval(iloc(1))*q_eigvec(:, iloc(1))
3313 q_b_matrix(:, iloc(1)) = q_eigval(iloc(1))*q_eigvec(:, iloc(1))
3316 trq = trq - q_eigval(iloc(1))
3320 IF (ispin == 1)
THEN
3321 q_a_matrix(:, :) = matmul(q_a_matrix, transpose(q_eigvec))
3323 q_b_matrix(:, :) = matmul(q_b_matrix, transpose(q_eigvec))
3326 DEALLOCATE (orb_occ)
3327 DEALLOCATE (q_eigval)
3328 DEALLOCATE (q_eigvec)
3334 trqxq_hund_j = 0.0_dp
3336 IF (ispin == 1)
THEN
3338 trq = trq + q_a_matrix(i, i)
3340 trq2 = trq2 + q_a_matrix(i, j)*q_a_matrix(j, i)
3341 trqxq_hund_j = trqxq_hund_j + q_a_matrix(i, j)*q_b_matrix(j, i)
3344 v_matrix(i, i) = u_minus_j*(0.5_dp - fspin*q_a_matrix(i, i))
3345 v_matrix(i, i) = v_matrix(i, i) + hund_j*fspin*q_b_matrix(i, i)
3346 IF (dft_control%mtlr_dft_with_perturbation .AND. &
3347 dft_control%mtlr_ikind == ikind .AND. &
3348 qs_kind_set(ikind)%dft_plus_u%lr_atom == atom_a)
THEN
3349 v_matrix(i, i) = v_matrix(i, i) + perturbation_strength
3352 v_matrix(i, j) = -u_minus_j*fspin*q_a_matrix(j, i)
3353 v_matrix(i, j) = v_matrix(i, j) + hund_j*fspin*q_b_matrix(j, i)
3359 trq = trq + q_b_matrix(i, i)
3361 trq2 = trq2 + q_b_matrix(i, j)*q_b_matrix(j, i)
3362 trqxq_hund_j = trqxq_hund_j + q_b_matrix(i, j)*q_a_matrix(j, i)
3365 v_matrix(i, i) = u_minus_j*(0.5_dp - fspin*q_b_matrix(i, i))
3366 v_matrix(i, i) = v_matrix(i, i) + hund_j*fspin*q_a_matrix(i, i)
3367 IF (dft_control%mtlr_dft_with_perturbation .AND. &
3368 dft_control%mtlr_ikind == ikind .AND. &
3369 qs_kind_set(ikind)%dft_plus_u%lr_atom == atom_a)
THEN
3370 v_matrix(i, i) = v_matrix(i, i) + perturbation_strength
3373 v_matrix(i, j) = -u_minus_j*fspin*q_b_matrix(j, i)
3374 v_matrix(i, j) = v_matrix(i, j) + hund_j*fspin*q_a_matrix(j, i)
3380 v_matrix(:, :) = matmul(s_inv_matrix, v_matrix)
3383 trq2 = fspin*fspin*trq2
3384 trqxq_hund_j = fspin*fspin*trqxq_hund_j
3386 energy%dft_plus_u = energy%dft_plus_u + 0.5_dp*u_minus_j*(trq - trq2)/fspin
3387 energy%dft_plus_u = energy%dft_plus_u + 0.5_dp*hund_j*trqxq_hund_j/fspin
3391 IF (.NOT. just_energy)
THEN
3393 CALL dbcsr_get_block_p(matrix=sm_v, &
3398 cpassert(
ASSOCIATED(v_block))
3400 CALL dbcsr_get_block_p(matrix=sm_a, &
3405 cpassert(
ASSOCIATED(a_block))
3409 DO ishell = 1, nshell(iset)
3410 IF (l(ishell, iset) /= lu) cycle
3413 DO isgf = first_sgf(ishell, iset), last_sgf(ishell, iset)
3417 DO jshell = 1, nshell(jset)
3418 IF (l(jshell, jset) /= lu) cycle
3421 DO jsgf = first_sgf(jshell, jset), last_sgf(jshell, jset)
3423 v_block(isgf, jsgf) = v_matrix(i, j)*a(isb)*a(jsb)
3424 a_block(isgf, jsgf) = s_inv_matrix(i, j)*a(isb)*a(jsb)
3438 IF (should_output .AND. (print_level > low_print_level))
THEN
3439 IF (ispin == 1)
THEN
3440 CALL para_env%sum(q_a_matrix)
3442 CALL para_env%sum(q_b_matrix)
3445 IF (output_unit > 0)
THEN
3446 ALLOCATE (q_work(nsb, nsbsize))
3447 q_work(:, :) = 0.0_dp
3451 DO i = (isb - 1)*nsbsize + 1, isb*nsbsize
3453 IF (ispin == 1)
THEN
3454 q_work(isb, j) = q_a_matrix(i, i)
3456 q_work(isb, j) = q_b_matrix(i, i)
3462 WRITE (unit=output_unit, fmt=
"(T3,I6,2X,I6,2X,10F8.3)") &
3463 atom_a, isb, q_work(isb, :), sum(q_work(isb, :))
3466 WRITE (unit=output_unit, fmt=
"(T12,A,2X,10F8.3)") &
3467 "Total", (sum(q_work(:, i)), i=1, nsbsize), sum(q_work)
3468 WRITE (unit=output_unit, fmt=
"(A)")
""
3473 WRITE (unit=output_unit, fmt=
"(T9,70I10)") (i, i=1, n)
3475 IF (ispin == 1)
THEN
3476 WRITE (unit=output_unit, fmt=
"(T3,I6,70F10.6)") i, q_a_matrix(i, :)
3478 WRITE (unit=output_unit, fmt=
"(T3,I6,70F10.6)") i, q_b_matrix(i, :)
3482 ALLOCATE (q_eigval(n))
3483 ALLOCATE (q_eigvec(n, n))
3484 q_eigval(:) = 0.0_dp
3485 q_eigvec(:, :) = 0.0_dp
3487 IF (ispin == 1)
THEN
3488 CALL jacobi(q_a_matrix, q_eigval, q_eigvec)
3490 CALL jacobi(q_b_matrix, q_eigval, q_eigvec)
3493 WRITE (unit=output_unit, fmt=
"(/,T9,70I10)") (i, i=1, n)
3494 WRITE (unit=output_unit, fmt=
"(T9,71F10.6)") (q_eigval(i), i=1, n), sum(q_eigval(1:n))
3497 WRITE (unit=output_unit, fmt=
"(T3,I6,70F10.6)") i, q_eigvec(i, :)
3500 DEALLOCATE (q_eigval)
3501 DEALLOCATE (q_eigvec)
3506 ALLOCATE (q_work(nsgf_kind, nsgf_kind))
3507 q_work(:, :) = 0.0_dp
3509 IF (ispin == 1)
THEN
3510 IF (
ASSOCIATED(q_a_block)) q_work(:, :) = q_a_block(:, :)
3512 IF (
ASSOCIATED(q_b_block)) q_work(:, :) = q_b_block(:, :)
3515 CALL para_env%sum(q_work)
3517 IF (output_unit > 0)
THEN
3518 norb =
SIZE(q_work, 1)
3520 WRITE (unit=output_unit, fmt=
"(/,T9,200I10)") (i, i=1, norb)
3522 WRITE (unit=output_unit, fmt=
"(T3,I6,200F10.6)") i, q_work(i, :)
3525 ALLOCATE (q_eigval(norb))
3526 ALLOCATE (q_eigvec(norb, norb))
3527 q_eigval(:) = 0.0_dp
3528 q_eigvec(:, :) = 0.0_dp
3530 CALL jacobi(q_work, q_eigval, q_eigvec)
3532 WRITE (unit=output_unit, fmt=
"(/,T9,200I10)") (i, i=1, norb)
3533 WRITE (unit=output_unit, fmt=
"(T9,201F10.6)") (q_eigval(i), i=1, norb), sum(q_eigval(1:norb))
3536 WRITE (unit=output_unit, fmt=
"(T3,I6,200F10.6)") i, q_eigvec(i, :)
3539 DEALLOCATE (q_eigval)
3540 DEALLOCATE (q_eigvec)
3549 IF (
ALLOCATED(q_a_matrix))
DEALLOCATE (q_a_matrix)
3550 IF (
ALLOCATED(q_b_matrix))
DEALLOCATE (q_b_matrix)
3551 IF (
ALLOCATED(s_matrix))
DEALLOCATE (s_matrix)
3552 IF (
ALLOCATED(s_inv_matrix))
DEALLOCATE (s_inv_matrix)
3553 IF (
ALLOCATED(v_matrix))
DEALLOCATE (v_matrix)
3557 IF (dft_control%mtlr_dft_with_perturbation .AND. &
3558 dft_control%mtlr_ikind == ikind)
THEN
3559 dft_control%vhxc(ispin) = dft_control%vhxc(ispin)/real(n, dp)
3560 CALL para_env%sum(dft_control%vhxc(ispin))
3561 CALL para_env%sum(dft_control%trq(ispin))
3562 DEALLOCATE (vhxc_matrix)
3569 IF (
ASSOCIATED(sm_h))
THEN
3570 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, sm_s, sm_v, 0.0_dp, sm_mid)
3571 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, sm_mid, sm_s, 1.0_dp, sm_h)
3576 CALL dbcsr_deallocate_matrix(sm_mid)
3578 IF (
PRESENT(matrix_w))
THEN
3580 CALL get_qs_env(qs_env=qs_env, force=force)
3582 force(ikind)%tensorial_u(:, :) = 0.0_dp
3584 IF (nspin == 2)
THEN
3585 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, sm_s, matrix_p(1)%matrix, 0.0_dp, sm_b)
3586 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, sm_s, matrix_p(2)%matrix, 0.0_dp, sm_c)
3588 CALL dbcsr_multiply(
"N",
"N", 0.5_dp, sm_s, matrix_p(1)%matrix, 0.0_dp, sm_b)
3589 CALL dbcsr_multiply(
"N",
"N", 0.5_dp, sm_s, matrix_p(1)%matrix, 0.0_dp, sm_c)
3591 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, sm_b, sm_s, 0.0_dp, sm_i)
3592 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, sm_c, sm_s, 0.0_dp, sm_j)
3595 CALL dbcsr_desymmetrize(matrixkp_s(jj + 1, 1)%matrix, sm_k)
3597 CALL dbcsr_set(sm_f, 0.0_dp)
3599 CALL dbcsr_iterator_start(iter, sm_k)
3600 DO WHILE (dbcsr_iterator_blocks_left(iter))
3602 CALL dbcsr_iterator_next_block(iter, jatom, katom, tmp_block)
3603 IF (jatom == katom) cycle
3604 CALL dbcsr_put_block(matrix=sm_f, row=jatom, col=katom, block=tmp_block)
3606 CALL dbcsr_iterator_stop(iter)
3607 CALL dbcsr_finalize(sm_f)
3609 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, sm_b, sm_f, 0.0_dp, sm_d)
3610 CALL dbcsr_multiply(
"N",
"N", 1.0_dp, sm_c, sm_f, 0.0_dp, sm_e)
3612 ALLOCATE (a_matrix(nkind, nkind))
3613 ALLOCATE (d_matrix(nkind, nkind))
3614 ALLOCATE (e_matrix(nkind, nkind))
3615 ALLOCATE (i_matrix(nkind, nkind))
3616 ALLOCATE (j_matrix(nkind, nkind))
3617 ALLOCATE (dd_matrix(nkind, nkind))
3618 ALLOCATE (ee_matrix(nkind, nkind))
3619 ALLOCATE (ff_matrix(nkind, nkind))
3623 CALL get_atomic_kind(atomic_kind_set(ikind), &
3624 atom_list=atom_list, &
3625 natom=natom_of_kind)
3627 CALL get_qs_kind(qs_kind_set(ikind), &
3628 u_minus_j=u_minus_j, &
3629 l_of_dft_plus_u=lu, &
3630 basis_set=orb_basis_set, &
3633 dft_plus_u_atom=dft_plus_u_atom)
3635 IF (.NOT. dft_plus_u_atom) cycle
3636 IF (.NOT.
ASSOCIATED(orb_basis_set)) cycle
3638 IF (u_minus_j == 0.0_dp .AND. hund_j == 0.0_dp) cycle
3640 CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
3641 first_sgf=first_sgf, &
3643 last_sgf=last_sgf, &
3649 DO ishell = 1, nshell(iset)
3650 IF (l(ishell, iset) == lu) nsb = nsb + 1
3654 nsbsize = (2*lu + 1)
3657 ALLOCATE (a_matrix(ikind, ikind)%matrix(n, n, natom_of_kind))
3658 ALLOCATE (d_matrix(ikind, ikind)%matrix(n, n, natom_of_kind))
3659 ALLOCATE (e_matrix(ikind, ikind)%matrix(n, n, natom_of_kind))
3660 ALLOCATE (i_matrix(ikind, ikind)%matrix(n, n, natom_of_kind))
3661 ALLOCATE (j_matrix(ikind, ikind)%matrix(n, n, natom_of_kind))
3663 a_matrix(ikind, ikind)%matrix(:, :, :) = 0.0_dp
3664 d_matrix(ikind, ikind)%matrix(:, :, :) = 0.0_dp
3665 e_matrix(ikind, ikind)%matrix(:, :, :) = 0.0_dp
3666 i_matrix(ikind, ikind)%matrix(:, :, :) = 0.0_dp
3667 j_matrix(ikind, ikind)%matrix(:, :, :) = 0.0_dp
3669 DO iatom = 1, natom_of_kind
3671 atom_aa = atom_list(iatom)
3674 CALL dbcsr_get_block_p(matrix=sm_a, &
3681 CALL dbcsr_get_block_p(matrix=sm_d, &
3688 CALL dbcsr_get_block_p(matrix=sm_e, &
3695 CALL dbcsr_get_block_p(matrix=sm_i, &
3702 CALL dbcsr_get_block_p(matrix=sm_j, &
3708 IF (
ASSOCIATED(a_block) .AND.
ASSOCIATED(d_block) .AND.
ASSOCIATED(e_block) &
3709 .AND.
ASSOCIATED(i_block) .AND.
ASSOCIATED(j_block))
THEN
3713 DO ishell = 1, nshell(iset)
3714 IF (l(ishell, iset) /= lu) cycle
3715 DO isgf = first_sgf(ishell, iset), last_sgf(ishell, iset)
3719 DO jshell = 1, nshell(jset)
3720 IF (l(jshell, jset) /= lu) cycle
3721 DO jsgf = first_sgf(jshell, jset), last_sgf(jshell, jset)
3723 a_matrix(ikind, ikind)%matrix(i, j, iatom) = a_block(isgf, jsgf)
3724 d_matrix(ikind, ikind)%matrix(i, j, iatom) = -d_block(isgf, jsgf)
3725 e_matrix(ikind, ikind)%matrix(i, j, iatom) = -e_block(isgf, jsgf)
3726 i_matrix(ikind, ikind)%matrix(i, j, iatom) = i_block(isgf, jsgf)
3727 j_matrix(ikind, ikind)%matrix(i, j, iatom) = j_block(isgf, jsgf)
3739 CALL get_atomic_kind(atomic_kind_set(jkind), &
3740 atom_list=atom_list2, &
3741 natom=matom_of_kind)
3743 CALL get_qs_kind(qs_kind_set(jkind), nsgf=nsgf_kind2)
3745 IF (.NOT.
ALLOCATED(dd_matrix(ikind, jkind)%matrix))
THEN
3746 ALLOCATE (dd_matrix(ikind, jkind)%matrix(n, nsgf_kind2, natom_of_kind, matom_of_kind))
3747 dd_matrix(ikind, jkind)%matrix(:, :, :, :) = 0.0_dp
3750 IF (.NOT.
ALLOCATED(ee_matrix(ikind, jkind)%matrix))
THEN
3751 ALLOCATE (ee_matrix(ikind, jkind)%matrix(n, nsgf_kind2, natom_of_kind, matom_of_kind))
3752 ee_matrix(ikind, jkind)%matrix(:, :, :, :) = 0.0_dp
3755 IF (.NOT.
ALLOCATED(ff_matrix(ikind, jkind)%matrix))
THEN
3756 ALLOCATE (ff_matrix(ikind, jkind)%matrix(nsgf_kind2, n, natom_of_kind, matom_of_kind))
3757 ff_matrix(ikind, jkind)%matrix(:, :, :, :) = 0.0_dp
3760 DO jatom = 1, matom_of_kind
3762 atom_a = atom_list2(jatom)
3765 CALL dbcsr_get_block_p(matrix=sm_b, &
3772 CALL dbcsr_get_block_p(matrix=sm_c, &
3778 IF (
ASSOCIATED(d_block) .AND.
ASSOCIATED(e_block))
THEN
3781 DO ishell = 1, nshell(iset)
3782 IF (l(ishell, iset) /= lu) cycle
3783 DO isgf = first_sgf(ishell, iset), last_sgf(ishell, iset)
3785 dd_matrix(ikind, jkind)%matrix(i, :, iatom, jatom) = d_block(isgf, :)
3786 ee_matrix(ikind, jkind)%matrix(i, :, iatom, jatom) = e_block(isgf, :)
3793 CALL dbcsr_get_block_p(matrix=sm_f, &
3799 IF (
ASSOCIATED(f_block))
THEN
3802 DO ishell = 1, nshell(iset)
3803 IF (l(ishell, iset) /= lu) cycle
3804 DO isgf = first_sgf(ishell, iset), last_sgf(ishell, iset)
3806 ff_matrix(ikind, jkind)%matrix(:, i, iatom, jatom) = f_block(:, isgf)
3819 CALL get_atomic_kind(atomic_kind_set(ikind), &
3820 atom_list=atom_list, &
3821 natom=natom_of_kind)
3823 CALL get_qs_kind(qs_kind_set(ikind), &
3824 u_minus_j=u_minus_j, &
3825 l_of_dft_plus_u=lu, &
3826 basis_set=orb_basis_set, &
3829 dft_plus_u_atom=dft_plus_u_atom)
3831 IF (.NOT. dft_plus_u_atom) cycle
3832 IF (.NOT.
ASSOCIATED(orb_basis_set)) cycle
3834 IF (u_minus_j == 0.0_dp .AND. hund_j == 0.0_dp) cycle
3836 CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
3837 first_sgf=first_sgf, &
3839 last_sgf=last_sgf, &
3843 CALL para_env%sum(a_matrix(ikind, ikind)%matrix(:, :, :))
3844 CALL para_env%sum(d_matrix(ikind, ikind)%matrix(:, :, :))
3845 CALL para_env%sum(e_matrix(ikind, ikind)%matrix(:, :, :))
3846 CALL para_env%sum(i_matrix(ikind, ikind)%matrix(:, :, :))
3847 CALL para_env%sum(j_matrix(ikind, ikind)%matrix(:, :, :))
3850 CALL para_env%sum(dd_matrix(ikind, jkind)%matrix(:, :, :, :))
3851 CALL para_env%sum(ee_matrix(ikind, jkind)%matrix(:, :, :, :))
3852 CALL para_env%sum(ff_matrix(ikind, jkind)%matrix(:, :, :, :))
3861 CALL get_atomic_kind(atomic_kind_set(ikind), &
3862 atom_list=atom_list, &
3863 natom=natom_of_kind)
3865 CALL get_qs_kind(qs_kind_set(ikind), &
3866 u_minus_j=u_minus_j, &
3867 l_of_dft_plus_u=lu, &
3868 basis_set=orb_basis_set, &
3871 dft_plus_u_atom=dft_plus_u_atom)
3873 IF (.NOT. dft_plus_u_atom) cycle
3874 IF (.NOT.
ASSOCIATED(orb_basis_set)) cycle
3876 IF (u_minus_j == 0.0_dp .AND. hund_j == 0.0_dp) cycle
3878 CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
3879 first_sgf=first_sgf, &
3881 last_sgf=last_sgf, &
3887 DO ishell = 1, nshell(iset)
3888 IF (l(ishell, iset) == lu) nsb = nsb + 1
3892 nsbsize = (2*lu + 1)
3895 ALLOCATE (tmp_matrix1(n, n))
3896 ALLOCATE (tmp_matrix2(n, n))
3897 ALLOCATE (tmp_matrix3(n, n))
3899 DO iatom = 1, natom_of_kind
3901 atom_aa = atom_list(iatom)
3903 tmp_matrix1(:, :) = matmul(d_matrix(ikind, ikind)%matrix(:, :, iatom), &
3904 a_matrix(ikind, ikind)%matrix(:, :, iatom))
3905 tmp_matrix2(:, :) = matmul(e_matrix(ikind, ikind)%matrix(:, :, iatom), &
3906 a_matrix(ikind, ikind)%matrix(:, :, iatom))
3908 i_matrix(ikind, ikind)%matrix(:, :, iatom) = matmul(i_matrix(ikind, ikind)%matrix(:, :, iatom), &
3909 a_matrix(ikind, ikind)%matrix(:, :, iatom))
3910 j_matrix(ikind, ikind)%matrix(:, :, iatom) = matmul(j_matrix(ikind, ikind)%matrix(:, :, iatom), &
3911 a_matrix(ikind, ikind)%matrix(:, :, iatom))
3913 tmp_matrix3(:, :) = 0.5_dp*u_minus_j*tmp_matrix1 - &
3914 u_minus_j*matmul(tmp_matrix1, i_matrix(ikind, ikind)%matrix(:, :, iatom)) &
3915 + hund_j*matmul(tmp_matrix2, i_matrix(ikind, ikind)%matrix(:, :, iatom))
3916 tmp_matrix3(:, :) = tmp_matrix3 + 0.5_dp*u_minus_j*tmp_matrix2 - &
3917 u_minus_j*matmul(tmp_matrix2, j_matrix(ikind, ikind)%matrix(:, :, iatom)) &
3918 + hund_j*matmul(tmp_matrix1, j_matrix(ikind, ikind)%matrix(:, :, iatom))
3921 force(ikind)%tensorial_u(jj, iatom) = force(ikind)%tensorial_u(jj, iatom) + tmp_matrix3(i, i)
3926 CALL get_atomic_kind(atomic_kind_set(jkind), &
3927 atom_list=atom_list2, &
3928 natom=matom_of_kind)
3930 CALL get_qs_kind(qs_kind_set(jkind), nsgf=nsgf_kind2)
3932 DO jatom = 1, matom_of_kind
3934 atom_a = atom_list2(jatom)
3936 tmp_matrix1(:, :) = matmul(dd_matrix(ikind, jkind)%matrix(:, :, iatom, jatom), &
3937 ff_matrix(ikind, jkind)%matrix(:, :, iatom, jatom))
3938 tmp_matrix1(:, :) = matmul(tmp_matrix1, a_matrix(ikind, ikind)%matrix(:, :, iatom))
3940 tmp_matrix2(:, :) = matmul(ee_matrix(ikind, jkind)%matrix(:, :, iatom, jatom), &
3941 ff_matrix(ikind, jkind)%matrix(:, :, iatom, jatom))
3942 tmp_matrix2(:, :) = matmul(tmp_matrix2, a_matrix(ikind, ikind)%matrix(:, :, iatom))
3944 tmp_matrix3(:, :) = 0.5_dp*u_minus_j*tmp_matrix1 - &
3945 u_minus_j*matmul(tmp_matrix1, i_matrix(ikind, ikind)%matrix(:, :, iatom)) &
3946 + hund_j*matmul(tmp_matrix2, i_matrix(ikind, ikind)%matrix(:, :, iatom))
3947 tmp_matrix3(:, :) = tmp_matrix3 + 0.5_dp*u_minus_j*tmp_matrix2 - &
3948 u_minus_j*matmul(tmp_matrix2, j_matrix(ikind, ikind)%matrix(:, :, iatom)) &
3949 + hund_j*matmul(tmp_matrix1, j_matrix(ikind, ikind)%matrix(:, :, iatom))
3951 IF (atom_a /= atom_aa)
THEN
3953 force(jkind)%tensorial_u(jj, jatom) = force(jkind)%tensorial_u(jj, jatom) &
3962 DEALLOCATE (tmp_matrix1)
3963 DEALLOCATE (tmp_matrix2)
3964 DEALLOCATE (tmp_matrix3)
3970 IF (
ALLOCATED(a_matrix(ikind, ikind)%matrix))
DEALLOCATE (a_matrix(ikind, ikind)%matrix)
3971 IF (
ALLOCATED(d_matrix(ikind, ikind)%matrix))
DEALLOCATE (d_matrix(ikind, ikind)%matrix)
3972 IF (
ALLOCATED(e_matrix(ikind, ikind)%matrix))
DEALLOCATE (e_matrix(ikind, ikind)%matrix)
3973 IF (
ALLOCATED(i_matrix(ikind, ikind)%matrix))
DEALLOCATE (i_matrix(ikind, ikind)%matrix)
3974 IF (
ALLOCATED(j_matrix(ikind, ikind)%matrix))
DEALLOCATE (j_matrix(ikind, ikind)%matrix)
3977 IF (
ALLOCATED(dd_matrix(ikind, jkind)%matrix))
DEALLOCATE (dd_matrix(ikind, jkind)%matrix)
3978 IF (
ALLOCATED(ee_matrix(ikind, jkind)%matrix))
DEALLOCATE (ee_matrix(ikind, jkind)%matrix)
3979 IF (
ALLOCATED(ff_matrix(ikind, jkind)%matrix))
DEALLOCATE (ff_matrix(ikind, jkind)%matrix)
3984 DEALLOCATE (a_matrix)
3985 DEALLOCATE (d_matrix)
3986 DEALLOCATE (e_matrix)
3987 DEALLOCATE (i_matrix)
3988 DEALLOCATE (j_matrix)
3989 DEALLOCATE (dd_matrix)
3990 DEALLOCATE (ee_matrix)
3991 DEALLOCATE (ff_matrix)
3996 force(ikind)%tensorial_u(:, :) = force(ikind)%tensorial_u(:, :)*2.0_dp
3999 CALL date_and_time(values=timevalues)
4005 CALL para_env%sum(energy%dft_plus_u)
4007 IF (energy%dft_plus_u < 0.0_dp)
THEN
4008 CALL cp_warn(__location__, &
4009 "DFT+U energy contibution is negative possibly due "// &
4010 "to unphysical Lowdin charges. Check your input, "// &
4011 "if this warning persists or try a different method!")
4016 CALL dbcsr_deallocate_matrix(sm_q_a)
4017 CALL dbcsr_deallocate_matrix(sm_q_b)
4018 CALL dbcsr_deallocate_matrix(sm_v)
4019 CALL dbcsr_deallocate_matrix(sm_a)
4021 IF (
PRESENT(matrix_w))
THEN
4022 CALL dbcsr_deallocate_matrix(sm_b)
4023 CALL dbcsr_deallocate_matrix(sm_c)
4024 CALL dbcsr_deallocate_matrix(sm_d)
4025 CALL dbcsr_deallocate_matrix(sm_e)
4026 CALL dbcsr_deallocate_matrix(sm_f)
4027 CALL dbcsr_deallocate_matrix(sm_k)
4028 CALL dbcsr_deallocate_matrix(sm_i)
4029 CALL dbcsr_deallocate_matrix(sm_j)
4032 CALL timestop(handle)
4034 END SUBROUTINE tensorial
Define the atomic kind types and their sub types.
subroutine, public get_atomic_kind_set(atomic_kind_set, atom_of_kind, kind_of, natom_of_kind, maxatom, natom, nshell, fist_potential_present, shell_present, shell_adiabatic, shell_check_distance, damping_present)
Get attributes of an atomic kind set.
subroutine, public get_atomic_kind(atomic_kind, fist_potential, element_symbol, name, mass, kind_number, natom, atom_list, rcov, rvdw, z, qeff, apol, cpol, mm_radius, shell, shell_active, damping)
Get attributes of an atomic kind.
subroutine, public get_gto_basis_set(gto_basis_set, name, aliases, norm_type, kind_radius, ncgf, nset, nsgf, cgf_symbol, sgf_symbol, norm_cgf, set_radius, lmax, lmin, lx, ly, lz, m, ncgf_set, npgf, nsgf_set, nshell, cphi, pgf_radius, sphi, scon, zet, first_cgf, first_sgf, l, last_cgf, last_sgf, n, gcc, maxco, maxl, maxpgf, maxsgf_set, maxshell, maxso, nco_sum, npgf_sum, nshell_sum, maxder, short_kind_radius, npgf_seg_sum, ccon)
...
collects all references to literature in CP2K as new algorithms / method are included from literature...
integer, save, public dudarev1997
integer, save, public dudarev1998
Basic linear algebra operations for complex full matrices.
subroutine, public cp_cfm_transpose(matrix, trans, matrixt)
Transposes a BLACS distributed complex matrix.
subroutine, public cp_cfm_column_scale(matrix_a, scaling, first_col, source)
Scales columns of the full matrix by corresponding factors.
used for collecting diagonalization schemes available for cp_cfm_type
subroutine, public cp_cfm_heevd(matrix, eigenvectors, eigenvalues)
Perform a diagonalisation of a complex matrix.
Represents a complex full matrix distributed on many processors.
subroutine, public cp_cfm_release(matrix)
Releases a full matrix.
subroutine, public cp_fm_to_cfm(msourcer, msourcei, mtarget)
Construct a complex full matrix by taking its real and imaginary parts from two separate real-value f...
subroutine, public cp_cfm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
Creates a new full matrix with the given structure.
subroutine, public cp_cfm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, matrix_struct, para_env)
Returns information about a full matrix.
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_deallocate_matrix(matrix)
...
logical function, public dbcsr_iterator_blocks_left(iterator)
...
subroutine, public dbcsr_iterator_stop(iterator)
...
subroutine, public dbcsr_desymmetrize(matrix_a, matrix_b)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_get_block_p(matrix, row, col, block, found, row_size, col_size)
...
subroutine, public dbcsr_multiply(transa, transb, alpha, matrix_a, matrix_b, beta, matrix_c, first_row, last_row, first_column, last_column, first_k, last_k, retain_sparsity, filter_eps, flop)
...
subroutine, public dbcsr_init_p(matrix)
...
subroutine, public dbcsr_iterator_next_block(iterator, row, column, block, block_number_argument_has_been_removed, row_size, col_size, row_offset, col_offset, transposed)
...
subroutine, public dbcsr_finalize(matrix)
...
subroutine, public dbcsr_iterator_start(iterator, matrix, shared, dynamic, dynamic_byrows)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_put_block(matrix, row, col, block, summation)
...
subroutine, public dbcsr_set_diag(matrix, diag)
Copies the diagonal elements from the given array into the given matrix.
subroutine, public dbcsr_get_diag(matrix, diag)
Copies the diagonal elements from the given matrix into the given array.
subroutine, public dbcsr_get_block_diag(matrix, diag)
Copies the diagonal blocks of matrix into diag.
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, plan, check_plan)
Copy a DBCSR matrix to a BLACS matrix.
subroutine, public cp_dbcsr_plus_fm_fm_t(sparse_matrix, matrix_v, matrix_g, ncol, alpha, keep_sparsity, symmetry_mode)
performs the multiplication sparse_matrix+dense_mat*dens_mat^T if matrix_g is not explicitly given,...
subroutine, public copy_fm_to_dbcsr(fm, matrix, keep_sparsity)
Copy a BLACS matrix to a dbcsr matrix.
subroutine, public write_fm_with_basis_info(blacs_matrix, before, after, qs_env, para_env, first_row, last_row, first_col, last_col, output_unit, omit_headers)
Print a spherical matrix of blacs type.
subroutine, public cp_dbcsr_write_sparse_matrix(sparse_matrix, before, after, qs_env, para_env, first_row, last_row, first_col, last_col, scale, output_unit, omit_headers, cartesian_basis)
...
Basic linear algebra operations for full matrices.
subroutine, public cp_fm_transpose(matrix, matrixt)
transposes a matrix matrixt = matrix ^ T
subroutine, public cp_fm_schur_product(matrix_a, matrix_b, matrix_c)
computes the schur product of two matrices c_ij = a_ij * b_ij
subroutine, public cp_fm_scale_and_add(alpha, matrix_a, beta, matrix_b)
calc A <- alpha*A + beta*B optimized for alpha == 1.0 (just add beta*B) and beta == 0....
used for collecting some of the diagonalization schemes available for cp_fm_type. cp_fm_power also mo...
subroutine, public choose_eigv_solver(matrix, eigenvectors, eigenvalues, info)
Choose the Eigensolver depending on which library is available ELPA seems to be unstable for small sy...
represent the structure of a full matrix
represent a full matrix distributed on many processors
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_set_submatrix(fm, new_values, start_row, start_col, n_rows, n_cols, alpha, beta, transpose)
sets a submatrix of a full matrix fm(start_row:start_row+n_rows,start_col:start_col+n_cols) = alpha*o...
subroutine, public cp_fm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
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 ...
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 low_print_level
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...
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, file_access)
...
Add the DFT+U contribution to the Hamiltonian matrix.
subroutine, public lowdin_kp_population(kpoints, delta, alpha)
Cache the current occupations, optionally measure their residual and accept or mix them.
subroutine, public lowdin_kp_initial_density(qs_env, fmwork)
Complete the initial density's Lowdin coordinates, including atomic and density restarts.
subroutine, public lowdin_kp_kernel(qs_env, density, response)
Project a Bloch density response and return its orbital potential response, including +J.
subroutine, public lowdin_kp_prepare(kp, orbitals, use_real_wfn, smat)
Prepare selected Lowdin projectors and their reusable product workspace.
subroutine, public lowdin_kp_apply(kp, v, rmat, cmat)
Add B diag(v) B**H before any solver, DIIS residual, or history storage uses H(k).
subroutine, public lowdin_kp_apply_mo(kp, v, coeff, hc)
Add B diag(v) B**H C to the complex orbital gradient, without forming an AO matrix.
subroutine, public plus_u(qs_env, matrix_h, matrix_w)
Add the DFT+U contribution to the Hamiltonian matrix. Wrapper routine for all "+U" methods.
subroutine, public lowdin_kp_init(qs_env)
Select the AO columns used by the existing orbital-diagonal Lowdin functional.
subroutine, public lowdin_kp_forces(kpoints)
Add -dE_U/dS(k) to W(k), before its ordinary inverse Fourier transform. If A=S**(1/2),...
Defines the basic variable types.
integer, parameter, public dp
integer, parameter, public default_string_length
Types and basic routines needed for a kpoint calculation.
integer, parameter, public local_gemm_pu_gpu
Definition of mathematical constants and functions.
complex(kind=dp), parameter, public z_one
complex(kind=dp), parameter, public z_zero
Collection of simple mathematical functions and subroutines.
subroutine, public jacobi(a, d, v)
Jacobi matrix diagonalization. The eigenvalues are returned in vector d and the eigenvectors are retu...
Interface to the message passing library MPI.
compute mulliken charges we (currently) define them as c_i = 1/2 [ (PS)_{ii} + (SP)_{ii}...
character(len=6) function, public sgf_symbol(n, l, m)
Build a spherical orbital symbol (orbital labels for printing).
basic linear algebra operations for full matrixes
Define methods related to particle_type.
subroutine, public get_particle_set(particle_set, qs_kind_set, first_sgf, last_sgf, nsgf, nmao, basis, ncgf)
Get the components of a particle set.
Define the data structure for the particle information.
Definition of physical constants:
real(kind=dp), parameter, public evolt
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, matrix_vhxc, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Define the quickstep kind type and their sub types.
subroutine, public get_qs_kind(qs_kind, basis_set, basis_type, ncgf, nsgf, all_potential, tnadd_potential, gth_potential, sgp_potential, upf_potential, cneo_potential, se_parameter, dftb_parameter, xtb_parameter, dftb3_param, zatom, zeff, elec_conf, mao, lmax_dftb, alpha_core_charge, ccore_charge, core_charge, core_charge_radius, paw_proj_set, paw_atom, hard_radius, hard0_radius, max_rad_local, covalent_radius, vdw_radius, gpw_type_forced, harmonics, max_iso_not0, max_s_harm, grid_atom, ngrid_ang, ngrid_rad, lmax_rho0, dft_plus_u_atom, l_of_dft_plus_u, n_of_dft_plus_u, u_minus_j, hund_j, u_of_dft_plus_u, j_of_dft_plus_u, alpha_of_dft_plus_u, beta_of_dft_plus_u, j0_of_dft_plus_u, occupation_of_dft_plus_u, dispersion, bs_occupation, magnetization, no_optimize, addel, laddel, naddel, orbitals, max_scf, eps_scf, smear, u_ramping, u_minus_j_target, eps_u_ramping, proj_shell_charge, lr_atom, do_mtlr, u_j_loop, ao_coef, init_u_ramping_each_scf, reltmat, ghost, monovalent, floating, name, element_symbol, pao_basis_size, pao_model_file, pao_potentials, pao_descriptors, nelec)
Get attributes of an atomic kind.
subroutine, public set_qs_kind(qs_kind, paw_atom, ghost, floating, hard_radius, hard0_radius, covalent_radius, vdw_radius, lmax_rho0, zeff, no_optimize, dispersion, u_minus_j, hund_j, reltmat, dftb_parameter, xtb_parameter, elec_conf, pao_basis_size)
Set the components of an atomic kind data set.
subroutine, public get_qs_kind_set(qs_kind_set, all_potential_present, tnadd_potential_present, gth_potential_present, sgp_potential_present, paw_atom_present, dft_plus_u_atom_present, maxcgf, maxsgf, maxco, maxco_proj, maxgtops, maxlgto, maxlprj, maxnset, maxsgf_set, ncgf, npgf, nset, nsgf, nshell, maxpol, maxlppl, maxlppnl, maxppnl, nelectron, maxder, max_ngrid_rad, max_sph_harm, maxg_iso_not0, lmax_rho0, basis_rcut, do_mtlr_present, basis_type, total_zeff_corr, npgf_seg, cneo_potential_present, nkind_q, natom_q)
Get attributes of an atomic kind set.
Assembly of real and complex k-point operators from real-space DBCSR matrices. Outputs use the distri...
subroutine, public kpoint_operator_context_create(ctx, kpoints, ao_ao_fm, nspin)
Create an empty operator context. The context owns no buffers after this call; they are created on fi...
subroutine, public kpoint_operator_get(ctx, ikp, ispin, rsmat, cmat, fm_re, fm_im, mat_re, mat_im, matrix_row, slot, grid)
Assemble one operator for one global round and spin in one call: run the single-group transfer of the...
subroutine, public kpoint_operator_context_release(ctx)
Release the context together with every buffer it created. Call once, at the end of the fixed-layout ...
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
Provides all information about an atomic kind.
Represent a complex full matrix.
keeps the information about the structure of a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...
Keeps information about a specific k-point.
Contains information about kpoints.
stores all the informations relevant to an mpi environment
Provides all information about a quickstep kind.
Caller-owned assembly context for a fixed geometry and parallel layout. OT retains it for one inner S...
keeps the density in various representations, keeping track of which ones are valid.