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
323 if (hm%exxop%compute_single_precision)
then
331 energy_old = 1.0e20_real64
335 if (.not. rdm%do_basis)
then
340 write(
message(1),
'(a)')
'Calculating Coulomb and exchange matrix elements in basis'
341 write(
message(2),
'(a)')
'--this may take a while--'
344 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, &
345 rdm%l_index, rdm%twoint)
354 do iter = 1, rdm%max_iter
355 rdm%iter = rdm%iter + 1
356 write(
message(1),
'(a)')
'**********************************************************************'
357 write(
message(2),
'(a, i4)')
'Iteration:', iter
361 call scf_occ_no(rdm, namespace, gr, hm, space, st, energy_occ)
363 call scf_occ(rdm, namespace, gr, hm, space, st, energy_occ)
366 write(
message(1),
'(a)')
'Optimization of natural orbitals'
368 do icount = 1, maxcount
369 if (rdm%do_basis)
then
370 call scf_orb(rdm, namespace, gr, st, hm, space, energy)
372 call scf_orb_cg(rdm, namespace, space, gr, ions, ext_partners, st, ks, hm, energy)
374 energy_dif = energy - energy_old
376 if (rdm%do_basis)
then
377 if (abs(energy_dif)/abs(energy) < rdm%conv_ener .and. rdm%maxFO < rdm%tolerFO)
exit
383 if (xneg > 1.5e0_real64*xpos)
then
384 rdm%scale_f = 1.01_real64*rdm%scale_f
385 elseif (xneg < 1.1e0_real64*xpos)
then
386 rdm%scale_f = 0.95_real64* rdm%scale_f
393 rel_ener = abs(energy_occ-energy)/abs(energy)
396 write(
message(2),
'(a,1x,es20.10)')
'Rel. energy difference:', rel_ener
399 if (.not. rdm%hf .and. rdm%do_basis)
then
400 write(
message(1),
'(a,18x,es20.10)')
'Max F0:', rdm%maxFO
405 if (rdm%do_basis)
then
406 conv = (rel_ener < rdm%conv_ener) .and. rdm%maxFO < rdm%tolerFO
408 conv = rel_ener < rdm%conv_ener
412 if (rdm%toler > 1e-4_real64) rdm%toler = rdm%toler*1e-1_real64
416 if (rdm%do_basis)
then
418 safe_allocate(dpsi(1:gr%np, 1:st%d%dim))
419 safe_allocate(dpsi2(1:gr%np, 1:st%d%dim))
425 dpsi(ip,1) = dpsi(ip,1) + rdm%vecnat(ist, iorb)*dpsi2(ip,1)
432 call states_elec_dump(restart_dump, space, states_save, gr, hm%kpoints, ierr, iter=iter)
434 if (conv .or. iter == rdm%max_iter)
then
441 safe_deallocate_a(dpsi)
442 safe_deallocate_a(dpsi2)
444 call states_elec_dump(restart_dump, space, st, gr, hm%kpoints, ierr, iter=iter)
447 if (.not. rdm%hf)
then
449 write(
message(1),
'(a,18x,es20.10)')
'Max F0:', rdm%maxFO
455 message(1) =
'Unable to write states wavefunctions.'
462 if (any(outp%what) .and. outp%duringscf)
then
463 do what_i = lbound(outp%what, 1), ubound(outp%what, 1)
464 if (outp%what_now(what_i, iter))
then
465 write(dirname,
'(a,a,i4.4)') trim(outp%iter_dir),
"scf.", iter
466 call output_all(outp, namespace, space, dirname, gr, ions, iter, st, hm, ks)
467 call output_modelmb(outp, namespace, space, dirname, gr, ions, iter, st)
478 write(
message(1),
'(a,i3,a)')
'The calculation converged after ',rdm%iter,
' iterations'
482 write(
message(1),
'(a,i3,a)')
'The calculation did not converge after ', iter-1,
' iterations '
483 write(
message(2),
'(a,es15.5)')
'Relative energy difference between the last two iterations ', rel_ener
484 write(
message(3),
'(a,es15.5)')
'The maximal non-diagonal element of the Hermitian matrix F is ', rdm%maxFO
497 character(len=*),
intent(in) :: dir, fname
499 integer :: iunit, ist
500 real(real64),
allocatable :: photon_number_state (:), ekin_state (:), epot_state (:)
504 safe_allocate(photon_number_state(1:st%nst))
505 safe_allocate(ekin_state(1:st%nst))
506 safe_allocate(epot_state(1:st%nst))
508 if(st%system_grp%is_root())
then
510 iunit =
io_open(trim(dir) //
"/" // trim(fname), namespace, action=
'write')
516 if (rdm%do_basis)
then
517 write(iunit,
'(a)')
'Orbital optimization with [basis set]'
519 write(iunit,
'(a)')
'Orbital optimization with [conjugated gradients]'
524 write(iunit,
'(a)')
'Hartree Fock calculation'
528 if (hm%psolver%is_dressed)
then
529 write(iunit,
'(a)')
'Dressed state calculation'
536 write(iunit,
'(a, i4, a)')
'SCF converged in ', iter,
' iterations'
538 write(iunit,
'(a)')
'SCF *not* converged!'
544 write(iunit,
'(a,1x,f16.12)')
'Sum of occupation numbers:', rdm%occsum
549 if (hm%psolver%is_dressed)
then
550 call calc_photon_number(space, gr, st, hm%psolver%photons, photon_number_state, ekin_state, epot_state)
551 if(st%system_grp%is_root())
then
552 write(iunit,
'(a,1x,f14.12)')
'Total mode occupation:', hm%psolver%photons%number(1)
556 if(st%system_grp%is_root())
then
557 if (rdm%max_iter > 0)
then
558 write(iunit,
'(a)')
'Convergence:'
559 write(iunit,
'(6x, a, es15.8)')
'maxFO = ', rdm%maxFO
560 write(iunit,
'(6x, a, es15.8)')
'rel_ener = ', rel_ener
566 if (st%system_grp%is_root())
then
568 write(iunit,
'(a)')
'Natural occupation numbers:'
569 write(iunit,
'(a4,5x,a12)', advance=
'no')
'#st',
'Occupation'
570 if (.not. rdm%do_basis)
write(iunit,
'(5x,a12)', advance=
'no')
'conv'
571 if (hm%psolver%is_dressed)
write(iunit,
'(3(5x,a12))', advance=
'no')
'Mode Occ.',
'-1/2d^2/dq^2',
'1/2w^2q^2'
576 write(iunit,
'(i4,3x,f14.12)', advance=
'no') ist, st%occ(ist, 1)
577 if (.not. rdm%do_basis)
write(iunit,
'(3x,f14.12)', advance=
'no') rdm%eigens%diff(ist, 1)
578 if (hm%psolver%is_dressed)
then
579 write(iunit,
'(3(3x,f14.12))', advance=
'no') photon_number_state(ist), ekin_state(ist), epot_state(ist)
585 if (st%system_grp%is_root())
then
589 safe_deallocate_a(photon_number_state)
590 safe_deallocate_a(ekin_state)
591 safe_deallocate_a(epot_state)
598 subroutine calc_maxfo (namespace, hm, st, gr, rdm)
600 type(
rdm_t),
intent(inout) :: rdm
601 type(
grid_t),
intent(in) :: gr
605 real(real64),
allocatable :: lambda(:, :), FO(:, :)
610 safe_allocate(lambda(1:st%nst,1:st%nst))
611 safe_allocate(fo(1:st%nst, 1:st%nst))
621 fo(jst, ist) = - (lambda(jst, ist) - lambda(ist ,jst))
624 rdm%maxFO = maxval(abs(fo))
626 safe_deallocate_a(lambda)
627 safe_deallocate_a(fo)
633 subroutine calc_photon_number(space, gr, st, photons, photon_number_state, ekin_state, epot_state)
634 class(
space_t),
intent(in) :: space
635 type(
grid_t),
intent(in) :: gr
638 real(real64),
contiguous,
intent(out) :: photon_number_state(:)
639 real(real64),
contiguous,
intent(out) :: ekin_state(:)
640 real(real64),
contiguous,
intent(out) :: epot_state(:)
642 integer :: ist, dim_photon, ip
643 real(real64) :: q2_exp, laplace_exp
644 real(real64),
allocatable :: psi(:, :), psi_q2(:), dpsidq(:), d2psidq2(:)
649 dim_photon = space%dim
651 safe_allocate(psi(1:gr%np_part, 1))
652 safe_allocate(psi_q2(1:gr%np))
653 safe_allocate(dpsidq(1:gr%np_part))
654 safe_allocate(d2psidq2(1:gr%np))
656 photons%number(1) =
m_zero
664 laplace_exp =
dmf_dotp(gr, psi(:, 1), d2psidq2(:))
665 ekin_state(ist) = -
m_half*laplace_exp
670 psi_q2(ip) = psi(ip, 1) * gr%x_t(ip, dim_photon)**2
673 q2_exp =
dmf_dotp(gr, psi(:, 1), psi_q2(:))
674 epot_state(ist) =
m_half * photons%omega(1)**2 * q2_exp
678 photon_number_state(ist) = -
m_half*laplace_exp / photons%omega(1) +
m_half * photons%omega(1) * q2_exp
679 photon_number_state(ist) = photon_number_state(ist) -
m_half
682 photons%number(1) = photons%number(1) + (photon_number_state(ist) +
m_half)*st%occ(ist, 1)
686 photons%number(1) = photons%number(1) - st%qtot/
m_two
688 safe_deallocate_a(psi)
689 safe_deallocate_a(psi_q2)
690 safe_deallocate_a(dpsidq)
691 safe_deallocate_a(d2psidq2)
702 real(real64),
allocatable :: occin(:, :)
706 safe_allocate(occin(1:st%nst, 1:st%nik))
708 occin(1:st%nst, 1:st%nik) = st%occ(1:st%nst, 1:st%nik)
710 where(occin(:, :) >
m_one) occin(:, :) = st%smear%el_per_state
712 st%occ(:, :) = occin(:, :)
714 safe_deallocate_a(occin)
723 subroutine scf_occ_no(rdm, namespace, gr, hm, space, st, energy)
724 type(
rdm_t),
intent(inout) :: rdm
726 type(
grid_t),
intent(in) :: gr
730 real(real64),
intent(out) :: energy
736 write(
message(1),
'(a)')
'SKIP Optimization of occupation numbers'
747 rdm%occsum = sum(st%occ(1:st%nst, 1:st%nik))
749 write(
message(1),
'(a4,5x,a12)')
'#st',
'Occupation'
753 write(
message(1),
'(i4,3x,f11.9)') ist, st%occ(ist, 1)
757 write(
message(1),
'(a,1x,f13.9)')
'Sum of occupation numbers', rdm%occsum
765 subroutine scf_occ(rdm, namespace, gr, hm, space, st, energy)
766 type(
rdm_t),
target,
intent(inout) :: rdm
768 type(
grid_t),
intent(in) :: gr
770 class(
space_t),
intent(in) :: space
772 real(real64),
intent(out) :: energy
774 integer :: ist, icycle, ierr
775 real(real64) :: sumgi1, sumgi2, sumgim, mu1, mu2, mum, dinterv, thresh_occ
776 real(real64),
allocatable :: occin(:, :)
777 real(real64),
parameter :: smallocc = 0.00001_real64
778 real(real64),
allocatable :: theta(:)
779 real(real64) :: objective
780 integer,
parameter :: max_cycle = 200
785 write(
message(1),
'(a)')
'Optimization of occupation numbers'
788 safe_allocate(occin(1:st%nst, 1:st%nik))
789 safe_allocate(theta(1:st%nst))
797 thresh_occ = 1e-14_real64
800 occin(1:st%nst, 1:st%nik) = st%occ(1:st%nst, 1:st%nik)
801 where(occin(:, :) < smallocc) occin(:, :) = smallocc
802 where(occin(:, :) > st%smear%el_per_state - smallocc) occin(:, :) = st%smear%el_per_state - smallocc
807 st%occ(:, :) = occin(:, :)
822 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
824 sumgi1 = rdm%occsum - st%qtot
827 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
829 sumgi2 = rdm%occsum - st%qtot
832 do icycle = 1, max_cycle
833 if (sumgi1*sumgi2 <=
m_zero)
exit
840 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
842 sumgi1 = rdm%occsum - st%qtot
849 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
851 sumgi2 = rdm%occsum - st%qtot
859 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.0001_real64, &
861 sumgim = rdm%occsum - st%qtot
863 if (sumgi1*sumgim <
m_zero)
then
873 if (st%occ(ist,1) <= thresh_occ ) st%occ(ist,1) = thresh_occ
876 if (abs(sumgim) < rdm%toler .or. abs((mu1-mu2)*
m_half) < rdm%toler)
exit
881 if (icycle >= 50)
then
882 write(
message(1),
'(a,1x,f11.4)')
'Bisection ended without finding mu, sum of occupation numbers:', rdm%occsum
887 st%occ(ist, 1) = st%smear%el_per_state*
sin(theta(ist)*
m_pi*
m_two)**2
890 objective = objective + rdm%mu*(rdm%occsum - rdm%qtot)
893 write(
message(1),
'(a4,5x,a12)')
'#st',
'Occupation'
897 write(
message(1),
'(i4,3x,f14.12)') ist, st%occ(ist, 1)
901 write(
message(1),
'(a,3x,f11.9)')
'Sum of occupation numbers: ', rdm%occsum
905 safe_deallocate_a(occin)
906 safe_deallocate_a(theta)
914 integer,
intent(in) :: size
915 real(real64),
intent(in) :: theta(size)
916 real(real64),
intent(inout) :: objective
917 integer,
intent(in) :: getgrad
918 real(real64),
intent(inout) :: df(size)
921 real(real64) :: thresh_occ, thresh_theta
922 real(real64),
allocatable :: dE_dn(:),occ(:)
926 assert(
size == rdm_ptr%nst)
928 safe_allocate(de_dn(1:size))
929 safe_allocate(occ(1:size))
935 thresh_occ = 1e-14_real64
940 if (occ(ist) <= thresh_occ ) occ(ist) = thresh_occ
943 rdm_ptr%occsum = sum(occ(1:size))
950 if (occ(ist) <= thresh_occ )
then
956 objective = objective - rdm_ptr%mu*(rdm_ptr%occsum - rdm_ptr%qtot)
958 safe_deallocate_a(de_dn)
959 safe_deallocate_a(occ)
966 integer,
intent(in) :: iter
967 integer,
intent(in) :: size
968 real(real64),
intent(in) :: energy, maxdr, maxdf
969 real(real64),
intent(in) :: theta(size)
979 subroutine scf_orb(rdm, namespace, gr, st, hm, space, energy)
980 type(
rdm_t),
intent(inout) :: rdm
982 type(
grid_t),
intent(in) :: gr
985 class(
space_t),
intent(in) :: space
986 real(real64),
intent(out) :: energy
989 real(real64),
allocatable :: lambda(:, :), fo(:, :)
995 safe_allocate(lambda(1:st%nst,1:st%nst))
996 safe_allocate(fo(1:st%nst, 1:st%nst))
1004 if (rdm%iter==1)
then
1007 fo(ist, jst) =
m_half*(lambda(ist, jst) + lambda(jst, ist))
1008 fo(jst, ist) = fo(ist, jst)
1014 fo(jst, ist) = - ( lambda(jst, ist) - lambda(ist ,jst))
1017 rdm%maxfo = maxval(abs(fo))
1019 fo(ist, ist) = rdm%evalues(ist)
1021 if(abs(fo(jst, ist)) > rdm%scale_f)
then
1022 fo(jst, ist) = rdm%scale_f*fo(jst,ist)/abs(fo(jst, ist))
1024 fo(ist, jst) = fo(jst, ist)
1035 safe_deallocate_a(lambda)
1036 safe_deallocate_a(fo)
1046 subroutine scf_orb_cg(rdm, namespace, space, gr, ions, ext_partners, st, ks, hm, energy)
1047 type(
rdm_t),
intent(inout) :: rdm
1050 type(
grid_t),
intent(in) :: gr
1051 type(
ions_t),
intent(in) :: ions
1054 type(
v_ks_t),
intent(inout) :: ks
1056 real(real64),
intent(out) :: energy
1058 integer :: ik, ist, maxiter
1064 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners)
1065 call hm%update(gr, namespace, space, ext_partners)
1067 rdm%eigens%converged = 0
1068 if(st%system_grp%is_root() .and. .not.
debug%info)
then
1071 do ik = st%d%kpt%start, st%d%kpt%end
1072 rdm%eigens%matvec = 0
1073 maxiter = rdm%eigens%es_maxiter
1074 call deigensolver_cg(namespace, gr, st, hm, rdm%eigens%pre, rdm%eigens%tolerance, maxiter, &
1075 rdm%eigens%converged(ik), ik, rdm%eigens%diff(:, ik), rdm%eigens%energy_change_threshold, &
1076 rdm%eigens%orthogonalize_to_all, rdm%eigens%conjugate_direction)
1078 if (.not. rdm%eigens%folded_spectrum)
then
1080 rdm%eigens%converged(ik) = 0
1082 if(rdm%eigens%diff(ist, ik) < rdm%eigens%tolerance)
then
1083 rdm%eigens%converged(ik) = ist
1091 if(st%system_grp%is_root() .and. .not.
debug%info)
then
1092 write(stdout,
'(1x)')
1097 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners)
1098 call hm%update(gr, namespace, space, ext_partners)
1114 type(
grid_t),
intent(in) :: gr
1115 real(real64),
contiguous,
intent(out) :: lambda(:, :)
1116 type(
rdm_t),
intent(inout) :: rdm
1118 real(real64),
allocatable :: hpsi(:, :), hpsi1(:, :), dpsi(:, :), dpsi1(:, :)
1119 real(real64),
allocatable :: fock(:,:,:), FV(:,:)
1120 integer :: ist, iorb, jorb, jst
1127 if (.not. rdm%do_basis)
then
1128 safe_allocate(hpsi(1:gr%np,1:st%d%dim))
1129 safe_allocate(hpsi1(1:gr%np,1:st%d%dim))
1130 safe_allocate(dpsi(1:gr%np_part ,1:st%d%dim))
1131 safe_allocate(dpsi1(1:gr%np_part ,1:st%d%dim))
1137 do jorb = iorb, st%nst
1140 lambda(jorb, iorb) =
dmf_dotp(gr, dpsi1(:,1), hpsi(:,1))
1143 if (iorb /= jorb )
then
1145 lambda(iorb, jorb) =
dmf_dotp(gr, dpsi(:,1), hpsi1(:,1))
1153 safe_allocate(fv(1:st%nst, 1:st%nst))
1154 safe_allocate(fock(1:st%nst, 1:st%nst, 1:st%nst))
1160 fock(ist, jst, iorb) = st%occ(iorb, 1)*rdm%eone_int(ist,jst)
1163 fock(ist ,jst, iorb) = fock(ist, jst, iorb) + st%occ(iorb, 1)*st%occ(jorb, 1)*rdm%Coul(ist, jst, jorb) &
1164 -
sqrt(st%occ(iorb, 1))*
sqrt(st%occ(jorb, 1))*rdm%Exch(ist, jst, jorb)
1166 fock(jst, ist, iorb) = fock(ist, jst, iorb)
1173 call lalg_gemv(st%nst, st%nst,
m_one, fock(:,:,jorb), rdm%vecnat(:, jorb),
m_zero, fv(:, jorb))
1180 if (.not. rdm%do_basis)
then
1181 safe_deallocate_a(hpsi)
1182 safe_deallocate_a(hpsi1)
1183 safe_deallocate_a(dpsi)
1184 safe_deallocate_a(dpsi1)
1186 safe_deallocate_a(fv)
1187 safe_deallocate_a(fock)
1197 type(
rdm_t),
intent(inout) :: rdm
1199 real(real64),
contiguous,
intent(in) :: lambda(:, :)
1201 integer :: iorb, jorb, ist
1202 real(real64),
allocatable :: vecnat_new(:, :)
1204 push_sub(assign_eigenfunctions)
1206 safe_allocate(vecnat_new(1:st%nst, 1:st%nst))
1209 vecnat_new(ist, iorb) =
m_zero
1211 vecnat_new(ist , iorb) = vecnat_new(ist, iorb) + rdm%vecnat(ist, jorb)*lambda(jorb, iorb)
1216 rdm%vecnat(:, :) = vecnat_new(:, :)
1218 safe_deallocate_a(vecnat_new)
1220 pop_sub(assign_eigenfunctions)
1227 type(
rdm_t),
intent(in) :: rdm
1228 real(real64),
contiguous,
intent(in) :: occ(:)
1229 real(real64),
intent(out) :: energy
1230 real(real64),
contiguous,
optional,
intent(out) :: dE_dn(:)
1233 real(real64),
allocatable :: V_h(:), V_x(:), sqrt_occ(:)
1237 safe_allocate(v_h(1:rdm%nst))
1238 safe_allocate(v_x(1:rdm%nst))
1239 safe_allocate(sqrt_occ(1:rdm%nst))
1245 sqrt_occ(1:rdm%nst) =
sqrt(occ(1:rdm%nst))
1250 v_x(ist) = v_x(ist)*
m_half/max(sqrt_occ(ist), 1.0e-16_real64)
1255 if (
present(de_dn))
then
1256 de_dn(:) = rdm%eone(:) + v_h(:) + v_x(:)
1261 energy = energy + occ(ist)*rdm%eone(ist) &
1262 +
m_half*occ(ist)*v_h(ist) &
1266 safe_deallocate_a(sqrt_occ)
1267 safe_deallocate_a(v_h)
1268 safe_deallocate_a(v_x)
1276 type(
rdm_t),
intent(inout) :: rdm
1280 type(
grid_t),
intent(in) :: gr
1281 class(
space_t),
intent(in) :: space
1284 real(real64),
allocatable :: hpsi(:, :), rho1(:), rho(:), dpsi(:, :), dpsi2(:, :)
1285 real(real64),
allocatable :: v_ij(:,:,:,:,:)
1289 integer :: ist, jst, nspin_, iorb, jorb, ip
1294 nspin_ = min(st%d%nspin, 2)
1296 if (.not. rdm%do_basis)
then
1297 safe_allocate(hpsi(1:gr%np, 1:st%d%dim))
1298 safe_allocate(rho1(1:gr%np))
1299 safe_allocate(rho(1:gr%np))
1300 safe_allocate(dpsi(1:gr%np_part, 1:st%d%dim))
1301 safe_allocate(dpsi2(1:gr%np, 1:st%d%dim))
1302 safe_allocate(v_ij(1:gr%np, 1:st%nst, 1:st%nst, 1:st%nik, 1:st%nik))
1316 rdm%eone(ist) =
dmf_dotp(gr, dpsi(:, 1), hpsi(:, 1))
1332 rho1(ip) = dpsi(ip, 1)**2
1336 do jst = ist, st%nst
1337 rdm%hartree(ist, jst) =
dmf_dotp(gr, rho1, v_ij(:,jst, jst, 1, 1))
1338 rdm%hartree(jst, ist) = rdm%hartree(ist, jst)
1342 rho(ip) = dpsi2(ip, 1)*dpsi(ip, 1)
1345 rdm%exchange(ist, jst) =
dmf_dotp(gr, rho, v_ij(:, ist, jst, 1, 1))
1346 rdm%exchange(jst, ist) = rdm%exchange(ist, jst)
1351 safe_deallocate_a(hpsi)
1352 safe_deallocate_a(rho)
1353 safe_deallocate_a(rho1)
1354 safe_deallocate_a(dpsi)
1355 safe_deallocate_a(dpsi2)
1356 safe_deallocate_a(v_ij)
1364 dd = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1365 rdm%eone(iorb) = rdm%eone(iorb) + dd*rdm%eone_int(ist, jst)
1372 rdm%hartree(iorb ,jorb) =
m_zero
1373 rdm%exchange(iorb,jorb) =
m_zero
1376 dd = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1377 rdm%hartree(iorb ,jorb) = rdm%hartree(iorb ,jorb)+rdm%Coul(ist,jst, jorb)*dd
1378 rdm%exchange(iorb ,jorb) = rdm%exchange(iorb ,jorb)+rdm%Exch(ist,jst, jorb)*dd
1381 rdm%hartree(jorb, iorb) = rdm%hartree(iorb, jorb)
1382 rdm%exchange(jorb, iorb) = rdm%exchange(iorb, jorb)
1393 type(
rdm_t),
intent(inout) :: rdm
1397 class(
mesh_t),
intent(in) :: mesh
1399 real(real64),
allocatable :: hpsi(:, :)
1400 real(real64),
allocatable :: dpsi(:, :), dpsi2(:, :)
1405 safe_allocate(dpsi(1:mesh%np_part, 1:st%d%dim))
1406 safe_allocate(dpsi2(1:mesh%np, 1:st%d%dim))
1407 safe_allocate(hpsi(1:mesh%np, 1:st%d%dim))
1412 do jst = ist, st%nst
1418 rdm%eone_int(jst, ist) =
dmf_dotp(mesh, dpsi2(:, 1), hpsi(:, 1))
1419 rdm%eone_int(ist, jst) = rdm%eone_int(jst, ist)
1423 safe_deallocate_a(hpsi)
1424 safe_deallocate_a(dpsi)
1425 safe_deallocate_a(dpsi2)
1433 type(
rdm_t),
intent(inout) :: rdm
1435 integer :: ist, jst, kst, lst, iorb, icount
1436 logical :: inv_pairs
1437 real(real64) :: two_int, wij, wik, wil, wjk, wjl, wkl
1438 real(real64),
allocatable :: dm(:,:,:)
1442 safe_allocate(dm(1:rdm%nst, 1:rdm%nst, 1:rdm%nst))
1448 do iorb = 1, rdm%nst
1451 dm(ist, jst, iorb) = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1452 dm(jst, ist, iorb) = dm(ist, jst, iorb)
1457 do icount = 1, rdm%n_twoint
1459 ist = rdm%i_index(1,icount)
1460 jst = rdm%j_index(1,icount)
1461 kst = rdm%k_index(1,icount)
1462 lst = rdm%l_index(1,icount)
1464 two_int = rdm%twoint(icount)
1478 if(ist == kst .and. jst /= lst)
then
1483 if(ist == lst .and. jst /= kst)
then
1488 if(jst == kst .and. ist /= lst)
then
1493 if(jst == lst .and. ist /= kst)
then
1499 inv_pairs = (ist /= kst .or. jst /= lst)
1501 do iorb = 1, rdm%nst
1504 rdm%Coul(ist, jst, iorb) = rdm%Coul(ist, jst, iorb) + dm(kst, lst, iorb)*wkl*two_int
1505 if (inv_pairs) rdm%Coul(kst, lst, iorb) = rdm%Coul(kst, lst, iorb) + dm(ist, jst, iorb)*wij*two_int
1509 rdm%Exch(ist, kst, iorb) = rdm%Exch(ist, kst, iorb) + two_int*dm(jst, lst, iorb)*wik
1510 if (kst /= lst)
then
1511 rdm%Exch(ist, lst, iorb) = rdm%Exch(ist, lst, iorb) + two_int*dm(jst, kst, iorb)*wil
1513 if (ist /= jst)
then
1515 rdm%Exch(jst, kst, iorb) = rdm%Exch(jst, kst, iorb) + two_int*dm(ist, lst, iorb)*wjk
1517 if (inv_pairs) rdm%Exch(kst, jst, iorb) = rdm%Exch(kst, jst, iorb) + two_int*dm(ist, lst, iorb)
1520 if (ist /=jst .and. kst /= lst)
then
1521 if (jst >= lst)
then
1522 rdm%Exch(jst, lst, iorb) = rdm%Exch(jst, lst, iorb) + two_int*dm(ist, kst, iorb)*wjl
1524 if (inv_pairs) rdm%Exch(lst, jst, iorb) = rdm%Exch(lst, jst, iorb) + two_int*dm(ist, kst, iorb)
1534 rdm%Coul(jst, ist, iorb) = rdm%Coul(ist, jst, iorb)
1535 rdm%Exch(jst, ist, iorb) = rdm%Exch(ist, jst, iorb)
1540 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, dest_type, copy_data)
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.