40 use,
intrinsic :: iso_fortran_env
82 type(eigensolver_t) :: eigens
90 real(real64) :: occsum
92 real(real64) :: scale_f
94 real(real64) :: conv_ener
96 real(real64) :: tolerFO
98 real(real64),
allocatable :: eone(:)
99 real(real64),
allocatable :: eone_int(:, :)
100 real(real64),
allocatable :: twoint(:)
101 real(real64),
allocatable :: hartree(:, :)
102 real(real64),
allocatable :: exchange(:, :)
103 real(real64),
allocatable :: evalues(:)
104 real(real64),
allocatable :: vecnat(:, :)
105 real(real64),
allocatable :: Coul(:,:,:)
106 real(real64),
allocatable :: Exch(:,:,:)
108 integer,
allocatable :: i_index(:, :)
109 integer,
allocatable :: j_index(:, :)
110 integer,
allocatable :: k_index(:, :)
111 integer,
allocatable :: l_index(:, :)
114 type(rdm_t),
pointer :: rdm_ptr
119 subroutine rdmft_init(rdm, namespace, gr, st, hm, mc, space, fromScratch)
120 type(rdm_t),
intent(out) :: rdm
121 type(namespace_t),
intent(in) :: namespace
122 type(grid_t),
intent(inout) :: gr
123 type(states_elec_t),
intent(in) :: st
124 type(hamiltonian_elec_t),
intent(in) :: hm
125 type(multicomm_t),
intent(in) :: mc
126 class(space_t),
intent(in) :: space
127 logical,
intent(in) :: fromScratch
131 if(st%nst < st%qtot + 1)
then
132 message(1) =
"Too few states to run RDMFT calculation"
133 message(2) =
"Number of states should be at least the number of electrons plus one"
154 call parse_variable(namespace,
'RDMTolerance', 1.0e-7_real64, rdm%toler)
165 call parse_variable(namespace,
'RDMToleranceFO', 1.0e-4_real64, rdm%tolerFO)
190 if (rdm%do_basis .and. fromscratch)
then
191 call messages_write(
"RDMFT calculations with RDMBasis = yes cannot be started FromScratch", new_line=.
true.)
192 call messages_write(
"Run a calculation for independent particles first")
207 if (rdm%do_basis)
then
208 rdm%n_twoint = rdm%nst*(rdm%nst + 1)*(rdm%nst**2 + rdm%nst + 2)/8
209 safe_allocate(rdm%eone_int(1:rdm%nst, 1:rdm%nst))
210 safe_allocate(rdm%twoint(1:rdm%n_twoint))
211 safe_allocate(rdm%i_index(1:2,1:rdm%n_twoint))
212 safe_allocate(rdm%j_index(1:2,1:rdm%n_twoint))
213 safe_allocate(rdm%k_index(1:2,1:rdm%n_twoint))
214 safe_allocate(rdm%l_index(1:2,1:rdm%n_twoint))
215 safe_allocate(rdm%vecnat(1:rdm%nst, 1:rdm%nst))
216 safe_allocate(rdm%Coul(1:rdm%nst, 1:rdm%nst, 1:rdm%nst))
217 safe_allocate(rdm%Exch(1:rdm%nst, 1:rdm%nst, 1:rdm%nst))
232 safe_allocate(rdm%eone(1:rdm%nst))
233 safe_allocate(rdm%hartree(1:rdm%nst, 1:rdm%nst))
234 safe_allocate(rdm%exchange(1:rdm%nst, 1:rdm%nst))
235 safe_allocate(rdm%evalues(1:rdm%nst))
241 rdm%mu =
m_two*st%eigenval(max(int(st%qtot*
m_half), 1), 1)
244 rdm%scale_f = 1e-2_real64
254 type(
rdm_t),
intent(inout) :: rdm
258 safe_deallocate_a(rdm%evalues)
259 safe_deallocate_a(rdm%eone)
260 safe_deallocate_a(rdm%hartree)
261 safe_deallocate_a(rdm%exchange)
263 if (rdm%do_basis)
then
264 safe_deallocate_a(rdm%eone_int)
265 safe_deallocate_a(rdm%twoint)
266 safe_deallocate_a(rdm%i_index)
267 safe_deallocate_a(rdm%j_index)
268 safe_deallocate_a(rdm%k_index)
269 safe_deallocate_a(rdm%l_index)
270 safe_deallocate_a(rdm%vecnat)
271 safe_deallocate_a(rdm%Coul)
272 safe_deallocate_a(rdm%Exch)
283 subroutine scf_rdmft(rdm, namespace, space, mc, gr, ions, ext_partners, st, ks, hm, outp, restart_dump)
284 type(
rdm_t),
intent(inout) :: rdm
288 type(
grid_t),
intent(in) :: gr
289 type(
ions_t),
intent(in) :: ions
292 type(
v_ks_t),
intent(inout) :: ks
295 type(
restart_t),
intent(in) :: restart_dump
298 integer :: iter, icount, ip, ist, ierr, maxcount, iorb
299 integer(int64) :: what_i
300 real(real64) :: energy, energy_dif, energy_old, energy_occ, xpos, xneg, rel_ener
301 real(real64),
allocatable :: dpsi(:, :), dpsi2(:, :)
303 character(len=MAX_PATH_LEN) :: dirname
307 if (hm%d%ispin /= 1)
then
313 if (space%is_periodic())
then
318 if(st%parallel_in_states)
then
326 energy_old = 1.0e20_real64
330 if (.not. rdm%do_basis)
then
335 write(
message(1),
'(a)')
'Calculating Coulomb and exchange matrix elements in basis'
336 write(
message(2),
'(a)')
'--this may take a while--'
339 call two_body_me(gr, st, space, namespace, hm%kpoints, hm%exxop%psolver, 1, st%nst, rdm%i_index, rdm%j_index, rdm%k_index, &
340 rdm%l_index, rdm%twoint)
349 do iter = 1, rdm%max_iter
350 rdm%iter = rdm%iter + 1
351 write(
message(1),
'(a)')
'**********************************************************************'
352 write(
message(2),
'(a, i4)')
'Iteration:', iter
356 call scf_occ_no(rdm, namespace, gr, hm, space, st, energy_occ)
358 call scf_occ(rdm, namespace, gr, hm, space, st, energy_occ)
361 write(
message(1),
'(a)')
'Optimization of natural orbitals'
363 do icount = 1, maxcount
364 if (rdm%do_basis)
then
365 call scf_orb(rdm, namespace, gr, st, hm, space, energy)
367 call scf_orb_cg(rdm, namespace, space, gr, ions, ext_partners, st, ks, hm, energy)
369 energy_dif = energy - energy_old
371 if (rdm%do_basis)
then
372 if (abs(energy_dif)/abs(energy) < rdm%conv_ener .and. rdm%maxFO < rdm%tolerFO)
exit
373 if (energy_dif <
m_zero)
then
378 if (xneg > 1.5e0_real64*xpos)
then
379 rdm%scale_f = 1.01_real64*rdm%scale_f
380 elseif (xneg < 1.1e0_real64*xpos)
then
381 rdm%scale_f = 0.95_real64* rdm%scale_f
388 rel_ener = abs(energy_occ-energy)/abs(energy)
391 write(
message(2),
'(a,1x,es20.10)')
'Rel. energy difference:', rel_ener
394 if (.not. rdm%hf .and. rdm%do_basis)
then
395 write(
message(1),
'(a,18x,es20.10)')
'Max F0:', rdm%maxFO
400 if (rdm%do_basis)
then
401 conv = (rel_ener < rdm%conv_ener) .and. rdm%maxFO < rdm%tolerFO
403 conv = rel_ener < rdm%conv_ener
407 if (rdm%toler > 1e-4_real64) rdm%toler = rdm%toler*1e-1_real64
411 if (rdm%do_basis)
then
413 safe_allocate(dpsi(1:gr%np, 1:st%d%dim))
414 safe_allocate(dpsi2(1:gr%np, 1:st%d%dim))
420 dpsi(ip,1) = dpsi(ip,1) + rdm%vecnat(ist, iorb)*dpsi2(ip,1)
427 call states_elec_dump(restart_dump, space, states_save, gr, hm%kpoints, ierr, iter=iter)
429 if (conv .or. iter == rdm%max_iter)
then
436 safe_deallocate_a(dpsi)
437 safe_deallocate_a(dpsi2)
439 call states_elec_dump(restart_dump, space, st, gr, hm%kpoints, ierr, iter=iter)
442 if (.not. rdm%hf)
then
444 write(
message(1),
'(a,18x,es20.10)')
'Max F0:', rdm%maxFO
450 message(1) =
'Unable to write states wavefunctions.'
457 if (any(outp%what) .and. outp%duringscf)
then
458 do what_i = lbound(outp%what, 1), ubound(outp%what, 1)
459 if (outp%what_now(what_i, iter))
then
460 write(dirname,
'(a,a,i4.4)') trim(outp%iter_dir),
"scf.", iter
461 call output_all(outp, namespace, space, dirname, gr, ions, iter, st, hm, ks)
462 call output_modelmb(outp, namespace, space, dirname, gr, ions, iter, st)
473 write(
message(1),
'(a,i3,a)')
'The calculation converged after ',rdm%iter,
' iterations'
477 write(
message(1),
'(a,i3,a)')
'The calculation did not converge after ', iter-1,
' iterations '
478 write(
message(2),
'(a,es15.5)')
'Relative energy difference between the last two iterations ', rel_ener
479 write(
message(3),
'(a,es15.5)')
'The maximal non-diagonal element of the Hermitian matrix F is ', rdm%maxFO
492 character(len=*),
intent(in) :: dir, fname
494 integer :: iunit, ist
495 real(real64),
allocatable :: photon_number_state (:), ekin_state (:), epot_state (:)
499 safe_allocate(photon_number_state(1:st%nst))
500 safe_allocate(ekin_state(1:st%nst))
501 safe_allocate(epot_state(1:st%nst))
503 if(st%system_grp%is_root())
then
505 iunit =
io_open(trim(dir) //
"/" // trim(fname), namespace, action=
'write')
511 if (rdm%do_basis)
then
512 write(iunit,
'(a)')
'Orbital optimization with [basis set]'
514 write(iunit,
'(a)')
'Orbital optimization with [conjugated gradients]'
519 write(iunit,
'(a)')
'Hartree Fock calculation'
523 if (hm%psolver%is_dressed)
then
524 write(iunit,
'(a)')
'Dressed state calculation'
531 write(iunit,
'(a, i4, a)')
'SCF converged in ', iter,
' iterations'
533 write(iunit,
'(a)')
'SCF *not* converged!'
539 write(iunit,
'(a,1x,f16.12)')
'Sum of occupation numbers:', rdm%occsum
544 if (hm%psolver%is_dressed)
then
545 call calc_photon_number(space, gr, st, hm%psolver%photons, photon_number_state, ekin_state, epot_state)
546 if(st%system_grp%is_root())
then
547 write(iunit,
'(a,1x,f14.12)')
'Total mode occupation:', hm%psolver%photons%number(1)
551 if(st%system_grp%is_root())
then
552 if (rdm%max_iter > 0)
then
553 write(iunit,
'(a)')
'Convergence:'
554 write(iunit,
'(6x, a, es15.8)')
'maxFO = ', rdm%maxFO
555 write(iunit,
'(6x, a, es15.8)')
'rel_ener = ', rel_ener
561 if (st%system_grp%is_root())
then
563 write(iunit,
'(a)')
'Natural occupation numbers:'
564 write(iunit,
'(a4,5x,a12)', advance=
'no')
'#st',
'Occupation'
565 if (.not. rdm%do_basis)
write(iunit,
'(5x,a12)', advance=
'no')
'conv'
566 if (hm%psolver%is_dressed)
write(iunit,
'(3(5x,a12))', advance=
'no')
'Mode Occ.',
'-1/2d^2/dq^2',
'1/2w^2q^2'
571 write(iunit,
'(i4,3x,f14.12)', advance=
'no') ist, st%occ(ist, 1)
572 if (.not. rdm%do_basis)
write(iunit,
'(3x,f14.12)', advance=
'no') rdm%eigens%diff(ist, 1)
573 if (hm%psolver%is_dressed)
then
574 write(iunit,
'(3(3x,f14.12))', advance=
'no') photon_number_state(ist), ekin_state(ist), epot_state(ist)
580 if (st%system_grp%is_root())
then
584 safe_deallocate_a(photon_number_state)
585 safe_deallocate_a(ekin_state)
586 safe_deallocate_a(epot_state)
593 subroutine calc_maxfo (namespace, hm, st, gr, rdm)
595 type(
rdm_t),
intent(inout) :: rdm
596 type(
grid_t),
intent(in) :: gr
600 real(real64),
allocatable :: lambda(:, :), FO(:, :)
605 safe_allocate(lambda(1:st%nst,1:st%nst))
606 safe_allocate(fo(1:st%nst, 1:st%nst))
616 fo(jst, ist) = - (lambda(jst, ist) - lambda(ist ,jst))
619 rdm%maxFO = maxval(abs(fo))
621 safe_deallocate_a(lambda)
622 safe_deallocate_a(fo)
628 subroutine calc_photon_number(space, gr, st, photons, photon_number_state, ekin_state, epot_state)
629 class(
space_t),
intent(in) :: space
630 type(
grid_t),
intent(in) :: gr
633 real(real64),
intent(out) :: photon_number_state(:)
634 real(real64),
intent(out) :: ekin_state(:)
635 real(real64),
intent(out) :: epot_state(:)
637 integer :: ist, dim_photon, ip
638 real(real64) :: q2_exp, laplace_exp
639 real(real64),
allocatable :: psi(:, :), psi_q2(:), dpsidq(:), d2psidq2(:)
644 dim_photon = space%dim
646 safe_allocate(psi(1:gr%np_part, 1))
647 safe_allocate(psi_q2(1:gr%np))
648 safe_allocate(dpsidq(1:gr%np_part))
649 safe_allocate(d2psidq2(1:gr%np))
651 photons%number(1) =
m_zero
659 laplace_exp =
dmf_dotp(gr, psi(:, 1), d2psidq2(:))
660 ekin_state(ist) = -
m_half*laplace_exp
665 psi_q2(ip) = psi(ip, 1) * gr%x_t(ip, dim_photon)**2
668 q2_exp =
dmf_dotp(gr, psi(:, 1), psi_q2(:))
669 epot_state(ist) =
m_half * photons%omega(1)**2 * q2_exp
673 photon_number_state(ist) = -
m_half*laplace_exp / photons%omega(1) +
m_half * photons%omega(1) * q2_exp
674 photon_number_state(ist) = photon_number_state(ist) -
m_half
677 photons%number(1) = photons%number(1) + (photon_number_state(ist) +
m_half)*st%occ(ist, 1)
681 photons%number(1) = photons%number(1) - st%qtot/
m_two
683 safe_deallocate_a(psi)
684 safe_deallocate_a(psi_q2)
685 safe_deallocate_a(dpsidq)
686 safe_deallocate_a(d2psidq2)
697 real(real64),
allocatable :: occin(:, :)
701 safe_allocate(occin(1:st%nst, 1:st%nik))
703 occin(1:st%nst, 1:st%nik) = st%occ(1:st%nst, 1:st%nik)
705 where(occin(:, :) >
m_one) occin(:, :) = st%smear%el_per_state
707 st%occ(:, :) = occin(:, :)
709 safe_deallocate_a(occin)
718 subroutine scf_occ_no(rdm, namespace, gr, hm, space, st, energy)
719 type(
rdm_t),
intent(inout) :: rdm
721 type(
grid_t),
intent(in) :: gr
725 real(real64),
intent(out) :: energy
731 write(
message(1),
'(a)')
'SKIP Optimization of occupation numbers'
742 rdm%occsum = sum(st%occ(1:st%nst, 1:st%nik))
744 write(
message(1),
'(a4,5x,a12)')
'#st',
'Occupation'
748 write(
message(1),
'(i4,3x,f11.9)') ist, st%occ(ist, 1)
752 write(
message(1),
'(a,1x,f13.9)')
'Sum of occupation numbers', rdm%occsum
760 subroutine scf_occ(rdm, namespace, gr, hm, space, st, energy)
761 type(
rdm_t),
target,
intent(inout) :: rdm
763 type(
grid_t),
intent(in) :: gr
765 class(
space_t),
intent(in) :: space
767 real(real64),
intent(out) :: energy
769 integer :: ist, icycle, ierr
770 real(real64) :: sumgi1, sumgi2, sumgim, mu1, mu2, mum, dinterv, thresh_occ
771 real(real64),
allocatable :: occin(:, :)
772 real(real64),
parameter :: smallocc = 0.00001_real64
773 real(real64),
allocatable :: theta(:)
774 real(real64) :: objective
775 integer,
parameter :: max_cycle = 200
780 write(
message(1),
'(a)')
'Optimization of occupation numbers'
783 safe_allocate(occin(1:st%nst, 1:st%nik))
784 safe_allocate(theta(1:st%nst))
792 thresh_occ = 1e-14_real64
795 occin(1:st%nst, 1:st%nik) = st%occ(1:st%nst, 1:st%nik)
796 where(occin(:, :) < smallocc) occin(:, :) = smallocc
797 where(occin(:, :) > st%smear%el_per_state - smallocc) occin(:, :) = st%smear%el_per_state - smallocc
802 st%occ(:, :) = occin(:, :)
817 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
819 sumgi1 = rdm%occsum - st%qtot
822 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
824 sumgi2 = rdm%occsum - st%qtot
827 do icycle = 1, max_cycle
828 if (sumgi1*sumgi2 <=
m_zero)
exit
835 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
837 sumgi1 = rdm%occsum - st%qtot
844 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
846 sumgi2 = rdm%occsum - st%qtot
854 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.0001_real64, &
856 sumgim = rdm%occsum - st%qtot
858 if (sumgi1*sumgim <
m_zero)
then
868 if (st%occ(ist,1) <= thresh_occ ) st%occ(ist,1) = thresh_occ
871 if (abs(sumgim) < rdm%toler .or. abs((mu1-mu2)*
m_half) < rdm%toler)
exit
876 if (icycle >= 50)
then
877 write(
message(1),
'(a,1x,f11.4)')
'Bisection ended without finding mu, sum of occupation numbers:', rdm%occsum
882 st%occ(ist, 1) = st%smear%el_per_state*
sin(theta(ist)*
m_pi*
m_two)**2
885 objective = objective + rdm%mu*(rdm%occsum - rdm%qtot)
888 write(
message(1),
'(a4,5x,a12)')
'#st',
'Occupation'
892 write(
message(1),
'(i4,3x,f14.12)') ist, st%occ(ist, 1)
896 write(
message(1),
'(a,3x,f11.9)')
'Sum of occupation numbers: ', rdm%occsum
900 safe_deallocate_a(occin)
901 safe_deallocate_a(theta)
909 integer,
intent(in) :: size
910 real(real64),
intent(in) :: theta(size)
911 real(real64),
intent(inout) :: objective
912 integer,
intent(in) :: getgrad
913 real(real64),
intent(inout) :: df(size)
916 real(real64) :: thresh_occ, thresh_theta
917 real(real64),
allocatable :: dE_dn(:),occ(:)
921 assert(
size == rdm_ptr%nst)
923 safe_allocate(de_dn(1:size))
924 safe_allocate(occ(1:size))
930 thresh_occ = 1e-14_real64
935 if (occ(ist) <= thresh_occ ) occ(ist) = thresh_occ
938 rdm_ptr%occsum = sum(occ(1:size))
945 if (occ(ist) <= thresh_occ )
then
951 objective = objective - rdm_ptr%mu*(rdm_ptr%occsum - rdm_ptr%qtot)
953 safe_deallocate_a(de_dn)
954 safe_deallocate_a(occ)
961 integer,
intent(in) :: iter
962 integer,
intent(in) :: size
963 real(real64),
intent(in) :: energy, maxdr, maxdf
964 real(real64),
intent(in) :: theta(size)
974 subroutine scf_orb(rdm, namespace, gr, st, hm, space, energy)
975 type(
rdm_t),
intent(inout) :: rdm
977 type(
grid_t),
intent(in) :: gr
980 class(
space_t),
intent(in) :: space
981 real(real64),
intent(out) :: energy
984 real(real64),
allocatable :: lambda(:, :), fo(:, :)
990 safe_allocate(lambda(1:st%nst,1:st%nst))
991 safe_allocate(fo(1:st%nst, 1:st%nst))
999 if (rdm%iter==1)
then
1002 fo(ist, jst) =
m_half*(lambda(ist, jst) + lambda(jst, ist))
1003 fo(jst, ist) = fo(ist, jst)
1009 fo(jst, ist) = - ( lambda(jst, ist) - lambda(ist ,jst))
1012 rdm%maxfo = maxval(abs(fo))
1014 fo(ist, ist) = rdm%evalues(ist)
1016 if(abs(fo(jst, ist)) > rdm%scale_f)
then
1017 fo(jst, ist) = rdm%scale_f*fo(jst,ist)/abs(fo(jst, ist))
1019 fo(ist, jst) = fo(jst, ist)
1030 safe_deallocate_a(lambda)
1031 safe_deallocate_a(fo)
1041 subroutine scf_orb_cg(rdm, namespace, space, gr, ions, ext_partners, st, ks, hm, energy)
1042 type(
rdm_t),
intent(inout) :: rdm
1045 type(
grid_t),
intent(in) :: gr
1046 type(
ions_t),
intent(in) :: ions
1049 type(
v_ks_t),
intent(inout) :: ks
1051 real(real64),
intent(out) :: energy
1053 integer :: ik, ist, maxiter
1059 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners)
1060 call hm%update(gr, namespace, space, ext_partners)
1062 rdm%eigens%converged = 0
1063 if(st%system_grp%is_root() .and. .not.
debug%info)
then
1066 do ik = st%d%kpt%start, st%d%kpt%end
1067 rdm%eigens%matvec = 0
1068 maxiter = rdm%eigens%es_maxiter
1069 call deigensolver_cg(namespace, gr, st, hm, rdm%eigens%pre, rdm%eigens%tolerance, maxiter, &
1070 rdm%eigens%converged(ik), ik, rdm%eigens%diff(:, ik), rdm%eigens%energy_change_threshold, &
1071 rdm%eigens%orthogonalize_to_all, rdm%eigens%conjugate_direction)
1073 if (.not. rdm%eigens%folded_spectrum)
then
1075 rdm%eigens%converged(ik) = 0
1077 if(rdm%eigens%diff(ist, ik) < rdm%eigens%tolerance)
then
1078 rdm%eigens%converged(ik) = ist
1086 if(st%system_grp%is_root() .and. .not.
debug%info)
then
1087 write(stdout,
'(1x)')
1092 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners)
1093 call hm%update(gr, namespace, space, ext_partners)
1109 type(
grid_t),
intent(in) :: gr
1110 real(real64),
intent(out) :: lambda(:, :)
1111 type(
rdm_t),
intent(inout) :: rdm
1113 real(real64),
allocatable :: hpsi(:, :), hpsi1(:, :), dpsi(:, :), dpsi1(:, :)
1114 real(real64),
allocatable :: fock(:,:,:), FV(:,:)
1115 integer :: ist, iorb, jorb, jst
1122 if (.not. rdm%do_basis)
then
1123 safe_allocate(hpsi(1:gr%np,1:st%d%dim))
1124 safe_allocate(hpsi1(1:gr%np,1:st%d%dim))
1125 safe_allocate(dpsi(1:gr%np_part ,1:st%d%dim))
1126 safe_allocate(dpsi1(1:gr%np_part ,1:st%d%dim))
1132 do jorb = iorb, st%nst
1135 lambda(jorb, iorb) =
dmf_dotp(gr, dpsi1(:,1), hpsi(:,1))
1138 if (iorb /= jorb )
then
1140 lambda(iorb, jorb) =
dmf_dotp(gr, dpsi(:,1), hpsi1(:,1))
1148 safe_allocate(fv(1:st%nst, 1:st%nst))
1149 safe_allocate(fock(1:st%nst, 1:st%nst, 1:st%nst))
1155 fock(ist, jst, iorb) = st%occ(iorb, 1)*rdm%eone_int(ist,jst)
1158 fock(ist ,jst, iorb) = fock(ist, jst, iorb) + st%occ(iorb, 1)*st%occ(jorb, 1)*rdm%Coul(ist, jst, jorb) &
1159 -
sqrt(st%occ(iorb, 1))*
sqrt(st%occ(jorb, 1))*rdm%Exch(ist, jst, jorb)
1161 fock(jst, ist, iorb) = fock(ist, jst, iorb)
1168 call lalg_gemv(st%nst, st%nst,
m_one, fock(:,:,jorb), rdm%vecnat(:, jorb),
m_zero, fv(:, jorb))
1175 if (.not. rdm%do_basis)
then
1176 safe_deallocate_a(hpsi)
1177 safe_deallocate_a(hpsi1)
1178 safe_deallocate_a(dpsi)
1179 safe_deallocate_a(dpsi1)
1181 safe_deallocate_a(fv)
1182 safe_deallocate_a(fock)
1192 type(
rdm_t),
intent(inout) :: rdm
1194 real(real64),
intent(in) :: lambda(:, :)
1196 integer :: iorb, jorb, ist
1197 real(real64),
allocatable :: vecnat_new(:, :)
1199 push_sub(assign_eigenfunctions)
1201 safe_allocate(vecnat_new(1:st%nst, 1:st%nst))
1204 vecnat_new(ist, iorb) =
m_zero
1206 vecnat_new(ist , iorb) = vecnat_new(ist, iorb) + rdm%vecnat(ist, jorb)*lambda(jorb, iorb)
1211 rdm%vecnat(:, :) = vecnat_new(:, :)
1213 safe_deallocate_a(vecnat_new)
1215 pop_sub(assign_eigenfunctions)
1222 type(
rdm_t),
intent(in) :: rdm
1223 real(real64),
intent(in) :: occ(:)
1224 real(real64),
intent(out) :: energy
1225 real(real64),
optional,
intent(out) :: dE_dn(:)
1228 real(real64),
allocatable :: V_h(:), V_x(:), sqrt_occ(:)
1232 safe_allocate(v_h(1:rdm%nst))
1233 safe_allocate(v_x(1:rdm%nst))
1234 safe_allocate(sqrt_occ(1:rdm%nst))
1240 sqrt_occ(1:rdm%nst) =
sqrt(occ(1:rdm%nst))
1245 v_x(ist) = v_x(ist)*
m_half/max(sqrt_occ(ist), 1.0e-16_real64)
1250 if (
present(de_dn))
then
1251 de_dn(:) = rdm%eone(:) + v_h(:) + v_x(:)
1256 energy = energy + occ(ist)*rdm%eone(ist) &
1257 +
m_half*occ(ist)*v_h(ist) &
1261 safe_deallocate_a(sqrt_occ)
1262 safe_deallocate_a(v_h)
1263 safe_deallocate_a(v_x)
1271 type(
rdm_t),
intent(inout) :: rdm
1275 type(
grid_t),
intent(in) :: gr
1276 class(
space_t),
intent(in) :: space
1279 real(real64),
allocatable :: hpsi(:, :), rho1(:), rho(:), dpsi(:, :), dpsi2(:, :)
1280 real(real64),
allocatable :: v_ij(:,:,:,:,:)
1284 integer :: ist, jst, nspin_, iorb, jorb, ip
1289 nspin_ = min(st%d%nspin, 2)
1291 if (.not. rdm%do_basis)
then
1292 safe_allocate(hpsi(1:gr%np, 1:st%d%dim))
1293 safe_allocate(rho1(1:gr%np))
1294 safe_allocate(rho(1:gr%np))
1295 safe_allocate(dpsi(1:gr%np_part, 1:st%d%dim))
1296 safe_allocate(dpsi2(1:gr%np, 1:st%d%dim))
1297 safe_allocate(v_ij(1:gr%np, 1:st%nst, 1:st%nst, 1:st%nik, 1:st%nik))
1311 rdm%eone(ist) =
dmf_dotp(gr, dpsi(:, 1), hpsi(:, 1))
1327 rho1(ip) = dpsi(ip, 1)**2
1331 do jst = ist, st%nst
1332 rdm%hartree(ist, jst) =
dmf_dotp(gr, rho1, v_ij(:,jst, jst, 1, 1))
1333 rdm%hartree(jst, ist) = rdm%hartree(ist, jst)
1337 rho(ip) = dpsi2(ip, 1)*dpsi(ip, 1)
1340 rdm%exchange(ist, jst) =
dmf_dotp(gr, rho, v_ij(:, ist, jst, 1, 1))
1341 rdm%exchange(jst, ist) = rdm%exchange(ist, jst)
1346 safe_deallocate_a(hpsi)
1347 safe_deallocate_a(rho)
1348 safe_deallocate_a(rho1)
1349 safe_deallocate_a(dpsi)
1350 safe_deallocate_a(dpsi2)
1351 safe_deallocate_a(v_ij)
1359 dd = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1360 rdm%eone(iorb) = rdm%eone(iorb) + dd*rdm%eone_int(ist, jst)
1367 rdm%hartree(iorb ,jorb) =
m_zero
1368 rdm%exchange(iorb,jorb) =
m_zero
1371 dd = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1372 rdm%hartree(iorb ,jorb) = rdm%hartree(iorb ,jorb)+rdm%Coul(ist,jst, jorb)*dd
1373 rdm%exchange(iorb ,jorb) = rdm%exchange(iorb ,jorb)+rdm%Exch(ist,jst, jorb)*dd
1376 rdm%hartree(jorb, iorb) = rdm%hartree(iorb, jorb)
1377 rdm%exchange(jorb, iorb) = rdm%exchange(iorb, jorb)
1388 type(
rdm_t),
intent(inout) :: rdm
1392 class(
mesh_t),
intent(in) :: mesh
1394 real(real64),
allocatable :: hpsi(:, :)
1395 real(real64),
allocatable :: dpsi(:, :), dpsi2(:, :)
1400 safe_allocate(dpsi(1:mesh%np_part, 1:st%d%dim))
1401 safe_allocate(dpsi2(1:mesh%np, 1:st%d%dim))
1402 safe_allocate(hpsi(1:mesh%np, 1:st%d%dim))
1407 do jst = ist, st%nst
1413 rdm%eone_int(jst, ist) =
dmf_dotp(mesh, dpsi2(:, 1), hpsi(:, 1))
1414 rdm%eone_int(ist, jst) = rdm%eone_int(jst, ist)
1418 safe_deallocate_a(hpsi)
1419 safe_deallocate_a(dpsi)
1420 safe_deallocate_a(dpsi2)
1428 type(
rdm_t),
intent(inout) :: rdm
1430 integer :: ist, jst, kst, lst, iorb, icount
1431 logical :: inv_pairs
1432 real(real64) :: two_int, wij, wik, wil, wjk, wjl, wkl
1433 real(real64),
allocatable :: dm(:,:,:)
1437 safe_allocate(dm(1:rdm%nst, 1:rdm%nst, 1:rdm%nst))
1443 do iorb = 1, rdm%nst
1446 dm(ist, jst, iorb) = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1447 dm(jst, ist, iorb) = dm(ist, jst, iorb)
1452 do icount = 1, rdm%n_twoint
1454 ist = rdm%i_index(1,icount)
1455 jst = rdm%j_index(1,icount)
1456 kst = rdm%k_index(1,icount)
1457 lst = rdm%l_index(1,icount)
1459 two_int = rdm%twoint(icount)
1473 if(ist == kst .and. jst /= lst)
then
1478 if(ist == lst .and. jst /= kst)
then
1483 if(jst == kst .and. ist /= lst)
then
1488 if(jst == lst .and. ist /= kst)
then
1494 inv_pairs = (ist /= kst .or. jst /= lst)
1496 do iorb = 1, rdm%nst
1499 rdm%Coul(ist, jst, iorb) = rdm%Coul(ist, jst, iorb) + dm(kst, lst, iorb)*wkl*two_int
1500 if (inv_pairs) rdm%Coul(kst, lst, iorb) = rdm%Coul(kst, lst, iorb) + dm(ist, jst, iorb)*wij*two_int
1504 rdm%Exch(ist, kst, iorb) = rdm%Exch(ist, kst, iorb) + two_int*dm(jst, lst, iorb)*wik
1505 if (kst /= lst)
then
1506 rdm%Exch(ist, lst, iorb) = rdm%Exch(ist, lst, iorb) + two_int*dm(jst, kst, iorb)*wil
1508 if (ist /= jst)
then
1510 rdm%Exch(jst, kst, iorb) = rdm%Exch(jst, kst, iorb) + two_int*dm(ist, lst, iorb)*wjk
1512 if (inv_pairs) rdm%Exch(kst, jst, iorb) = rdm%Exch(kst, jst, iorb) + two_int*dm(ist, lst, iorb)
1515 if (ist /=jst .and. kst /= lst)
then
1516 if (jst >= lst)
then
1517 rdm%Exch(jst, lst, iorb) = rdm%Exch(jst, lst, iorb) + two_int*dm(ist, kst, iorb)*wjl
1519 if (inv_pairs) rdm%Exch(lst, jst, iorb) = rdm%Exch(lst, jst, iorb) + two_int*dm(ist, kst, iorb)
1529 rdm%Coul(jst, ist, iorb) = rdm%Coul(ist, jst, iorb)
1530 rdm%Exch(jst, ist, iorb) = rdm%Exch(ist, jst, iorb)
1535 safe_deallocate_a(dm)
The same as above but with (Hermitian) transpose of A.
Prints out to iunit a message in the form: ["InputVariable" = value] where "InputVariable" is given b...
double sin(double __x) __attribute__((__nothrow__
double asin(double __x) __attribute__((__nothrow__
type(debug_t), save, public debug
This module implements a calculator for the density and defines related functions.
subroutine, public density_calc(st, gr, density, istin)
Computes the density from the orbitals in st.
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
subroutine, public dderivatives_partial(der, ff, op_ff, dir, ghost_update, set_bc)
apply the partial derivative along dir to a mesh function
subroutine, public deigensolver_cg(namespace, mesh, st, hm, pre, tol, niter, converged, ik, diff, energy_change_threshold, orthogonalize_to_all, conjugate_direction, shift)
conjugate-gradients method.
subroutine, public eigensolver_init(eigens, namespace, gr, st, hm, mc, space, deactivate_oracle)
subroutine, public eigensolver_end(eigens)
subroutine, public dexchange_operator_compute_potentials(this, namespace, space, gr, st, xst, kpoints, F_out)
real(real64), parameter, public m_two
real(real64), parameter, public m_zero
real(real64), parameter, public m_four
real(real64), parameter, public m_pi
some mathematical constants
character(len= *), parameter, public static_dir
real(real64), parameter, public m_half
real(real64), parameter, public m_one
This module implements the underlying real-space grid.
subroutine, public grid_write_info(gr, iunit, namespace)
integer, parameter, public term_local_external
integer, parameter, public term_non_local_potential
integer, parameter, public term_kinetic
subroutine, public dhamiltonian_elec_apply_single(hm, namespace, mesh, psi, hpsi, ist, ik, terms, set_bc, set_phase)
This module defines classes and functions for interaction partners.
subroutine, public io_close(iunit, grp)
subroutine, public io_mkdir(fname, namespace, parents)
integer function, public io_open(file, namespace, action, status, form, position, die, recl, grp)
System information (time, memory, sysname)
subroutine, public loct_progress_bar(a, maxcount)
A wrapper around the progress bar, such that it can be silenced without needing to dress the call wit...
This module is intended to contain "only mathematical" functions and procedures.
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
subroutine, public messages_print_with_emphasis(msg, iunit, namespace)
subroutine, public messages_not_implemented(feature, namespace)
character(len=512), private msg
subroutine, public messages_warning(no_lines, all_nodes, namespace)
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
integer, parameter, public minmethod_bfgs
This module handles the communicators for the various parallelization strategies.
this module contains the low-level part of the output system
subroutine, public output_modelmb(outp, namespace, space, dir, gr, ions, iter, st)
this module contains the output system
subroutine, public output_all(outp, namespace, space, dir, gr, ions, iter, st, hm, ks)
subroutine, public photon_mode_write_info(this, iunit, namespace)
subroutine, public profiling_out(label)
Increment out counter and sum up difference between entry and exit time.
subroutine, public profiling_in(label, exclude)
Increment in counter and save entry time.
subroutine scf_occ(rdm, namespace, gr, hm, space, st, energy)
subroutine calc_maxfo(namespace, hm, st, gr, rdm)
subroutine objective_rdmft(size, theta, objective, getgrad, df)
subroutine scf_orb_cg(rdm, namespace, space, gr, ions, ext_partners, st, ks, hm, energy)
subroutine, public rdmft_end(rdm)
subroutine, public scf_rdmft(rdm, namespace, space, mc, gr, ions, ext_partners, st, ks, hm, outp, restart_dump)
subroutine, public rdmft_init(rdm, namespace, gr, st, hm, mc, space, fromScratch)
subroutine write_iter_info_rdmft(iter, size, energy, maxdr, maxdf, theta)
subroutine set_occ_pinning(st)
subroutine calc_photon_number(space, gr, st, photons, photon_number_state, ekin_state, epot_state)
subroutine assign_eigfunctions(rdm, st, lambda)
subroutine construct_lambda(namespace, hm, st, gr, lambda, rdm)
subroutine sum_integrals(rdm)
subroutine rdm_integrals(rdm, namespace, hm, st, mesh)
subroutine scf_orb(rdm, namespace, gr, st, hm, space, energy)
subroutine total_energy_rdm(rdm, occ, energy, dE_dn)
subroutine scf_occ_no(rdm, namespace, gr, hm, space, st, energy)
subroutine rdm_derivatives(rdm, namespace, hm, st, gr, space)
pure logical function, public states_are_complex(st)
subroutine, public states_elec_end(st)
finalize the states_elec_t object
subroutine, public states_elec_copy(stout, stin, exclude_wfns, exclude_eigenval, special)
make a (selective) copy of a states_elec_t object
This module handles reading and writing restart information for the states_elec_t.
subroutine, public states_elec_dump(restart, space, st, mesh, kpoints, ierr, iter, lr, verbose)
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
character(len=20) pure function, public units_abbrev(this)
This module defines the unit system, used for input and output.
type(unit_system_t), public units_out
subroutine, public v_ks_write_info(ks, iunit, namespace)
subroutine, public v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners, calc_eigenval, time, calc_energy, calc_current, force_semilocal)
This module provices a simple timer class which can be used to trigger the writing of a restart file ...
logical function, public restart_walltime_period_alarm(comm)
subroutine scf_write_static(dir, fname)
Extension of space that contains the knowledge of the spin dimension.
Description of the grid, containing information on derivatives, stencil, and symmetries.
Describes mesh distribution to nodes.
Stores all communicators and groups.
The states_elec_t class contains all electronic wave functions.