40 use,
intrinsic :: iso_fortran_env
81 type(eigensolver_t) :: eigens
89 real(real64) :: occsum
91 real(real64) :: scale_f
93 real(real64) :: conv_ener
95 real(real64) :: tolerFO
97 real(real64),
allocatable :: eone(:)
98 real(real64),
allocatable :: eone_int(:, :)
99 real(real64),
allocatable :: twoint(:)
100 real(real64),
allocatable :: hartree(:, :)
101 real(real64),
allocatable :: exchange(:, :)
102 real(real64),
allocatable :: evalues(:)
103 real(real64),
allocatable :: vecnat(:, :)
104 real(real64),
allocatable :: Coul(:,:,:)
105 real(real64),
allocatable :: Exch(:,:,:)
107 integer,
allocatable :: i_index(:, :)
108 integer,
allocatable :: j_index(:, :)
109 integer,
allocatable :: k_index(:, :)
110 integer,
allocatable :: l_index(:, :)
113 type(rdm_t),
pointer :: rdm_ptr
118 subroutine rdmft_init(rdm, namespace, gr, st, hm, mc, space, fromScratch)
119 type(rdm_t),
intent(out) :: rdm
120 type(namespace_t),
intent(in) :: namespace
121 type(grid_t),
intent(inout) :: gr
122 type(states_elec_t),
intent(in) :: st
123 type(hamiltonian_elec_t),
intent(in) :: hm
124 type(multicomm_t),
intent(in) :: mc
125 class(space_t),
intent(in) :: space
126 logical,
intent(in) :: fromScratch
130 if(st%nst < st%qtot + 1)
then
131 message(1) =
"Too few states to run RDMFT calculation"
132 message(2) =
"Number of states should be at least the number of electrons plus one"
153 call parse_variable(namespace,
'RDMTolerance', 1.0e-7_real64, rdm%toler)
164 call parse_variable(namespace,
'RDMToleranceFO', 1.0e-4_real64, rdm%tolerFO)
189 if (rdm%do_basis .and. fromscratch)
then
190 call messages_write(
"RDMFT calculations with RDMBasis = yes cannot be started FromScratch", new_line=.
true.)
191 call messages_write(
"Run a calculation for independent particles first")
206 if (rdm%do_basis)
then
207 rdm%n_twoint = rdm%nst*(rdm%nst + 1)*(rdm%nst**2 + rdm%nst + 2)/8
208 safe_allocate(rdm%eone_int(1:rdm%nst, 1:rdm%nst))
209 safe_allocate(rdm%twoint(1:rdm%n_twoint))
210 safe_allocate(rdm%i_index(1:2,1:rdm%n_twoint))
211 safe_allocate(rdm%j_index(1:2,1:rdm%n_twoint))
212 safe_allocate(rdm%k_index(1:2,1:rdm%n_twoint))
213 safe_allocate(rdm%l_index(1:2,1:rdm%n_twoint))
214 safe_allocate(rdm%vecnat(1:rdm%nst, 1:rdm%nst))
215 safe_allocate(rdm%Coul(1:rdm%nst, 1:rdm%nst, 1:rdm%nst))
216 safe_allocate(rdm%Exch(1:rdm%nst, 1:rdm%nst, 1:rdm%nst))
231 safe_allocate(rdm%eone(1:rdm%nst))
232 safe_allocate(rdm%hartree(1:rdm%nst, 1:rdm%nst))
233 safe_allocate(rdm%exchange(1:rdm%nst, 1:rdm%nst))
234 safe_allocate(rdm%evalues(1:rdm%nst))
240 rdm%mu =
m_two*st%eigenval(max(int(st%qtot*
m_half), 1), 1)
243 rdm%scale_f = 1e-2_real64
253 type(
rdm_t),
intent(inout) :: rdm
257 safe_deallocate_a(rdm%evalues)
258 safe_deallocate_a(rdm%eone)
259 safe_deallocate_a(rdm%hartree)
260 safe_deallocate_a(rdm%exchange)
262 if (rdm%do_basis)
then
263 safe_deallocate_a(rdm%eone_int)
264 safe_deallocate_a(rdm%twoint)
265 safe_deallocate_a(rdm%i_index)
266 safe_deallocate_a(rdm%j_index)
267 safe_deallocate_a(rdm%k_index)
268 safe_deallocate_a(rdm%l_index)
269 safe_deallocate_a(rdm%vecnat)
270 safe_deallocate_a(rdm%Coul)
271 safe_deallocate_a(rdm%Exch)
282 subroutine scf_rdmft(rdm, namespace, space, mc, gr, ions, ext_partners, st, ks, hm, outp, restart_dump)
283 type(
rdm_t),
intent(inout) :: rdm
287 type(
grid_t),
intent(in) :: gr
288 type(
ions_t),
intent(in) :: ions
291 type(
v_ks_t),
intent(inout) :: ks
294 type(
restart_t),
intent(in) :: restart_dump
297 integer :: iter, icount, ip, ist, ierr, maxcount, iorb
298 integer(int64) :: what_i
299 real(real64) :: energy, energy_dif, energy_old, energy_occ, xpos, xneg, rel_ener
300 real(real64),
allocatable :: dpsi(:, :), dpsi2(:, :)
302 character(len=MAX_PATH_LEN) :: dirname
306 if (hm%d%ispin /= 1)
then
312 if (space%is_periodic())
then
317 if(st%parallel_in_states)
then
325 energy_old = 1.0e20_real64
329 if (.not. rdm%do_basis)
then
334 write(
message(1),
'(a)')
'Calculating Coulomb and exchange matrix elements in basis'
335 write(
message(2),
'(a)')
'--this may take a while--'
338 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, &
339 rdm%l_index, rdm%twoint)
348 do iter = 1, rdm%max_iter
349 rdm%iter = rdm%iter + 1
350 write(
message(1),
'(a)')
'**********************************************************************'
351 write(
message(2),
'(a, i4)')
'Iteration:', iter
355 call scf_occ_no(rdm, namespace, gr, hm, space, st, energy_occ)
357 call scf_occ(rdm, namespace, gr, hm, space, st, energy_occ)
360 write(
message(1),
'(a)')
'Optimization of natural orbitals'
362 do icount = 1, maxcount
363 if (rdm%do_basis)
then
364 call scf_orb(rdm, namespace, gr, st, hm, space, energy)
366 call scf_orb_cg(rdm, namespace, space, gr, ions, ext_partners, st, ks, hm, energy)
368 energy_dif = energy - energy_old
370 if (rdm%do_basis)
then
371 if (abs(energy_dif)/abs(energy) < rdm%conv_ener .and. rdm%maxFO < rdm%tolerFO)
exit
372 if (energy_dif <
m_zero)
then
377 if (xneg > 1.5e0_real64*xpos)
then
378 rdm%scale_f = 1.01_real64*rdm%scale_f
379 elseif (xneg < 1.1e0_real64*xpos)
then
380 rdm%scale_f = 0.95_real64* rdm%scale_f
387 rel_ener = abs(energy_occ-energy)/abs(energy)
390 write(
message(2),
'(a,1x,es20.10)')
'Rel. energy difference:', rel_ener
393 if (.not. rdm%hf .and. rdm%do_basis)
then
394 write(
message(1),
'(a,18x,es20.10)')
'Max F0:', rdm%maxFO
399 if (rdm%do_basis)
then
400 conv = (rel_ener < rdm%conv_ener) .and. rdm%maxFO < rdm%tolerFO
402 conv = rel_ener < rdm%conv_ener
406 if (rdm%toler > 1e-4_real64) rdm%toler = rdm%toler*1e-1_real64
410 if (rdm%do_basis)
then
412 safe_allocate(dpsi(1:gr%np, 1:st%d%dim))
413 safe_allocate(dpsi2(1:gr%np, 1:st%d%dim))
419 dpsi(ip,1) = dpsi(ip,1) + rdm%vecnat(ist, iorb)*dpsi2(ip,1)
426 call states_elec_dump(restart_dump, space, states_save, gr, hm%kpoints, ierr, iter=iter)
428 if (conv .or. iter == rdm%max_iter)
then
435 safe_deallocate_a(dpsi)
436 safe_deallocate_a(dpsi2)
438 call states_elec_dump(restart_dump, space, st, gr, hm%kpoints, ierr, iter=iter)
441 if (.not. rdm%hf)
then
443 write(
message(1),
'(a,18x,es20.10)')
'Max F0:', rdm%maxFO
449 message(1) =
'Unable to write states wavefunctions.'
456 if (any(outp%what) .and. outp%duringscf)
then
457 do what_i = lbound(outp%what, 1), ubound(outp%what, 1)
458 if (outp%what_now(what_i, iter))
then
459 write(dirname,
'(a,a,i4.4)') trim(outp%iter_dir),
"scf.", iter
460 call output_all(outp, namespace, space, dirname, gr, ions, iter, st, hm, ks)
461 call output_modelmb(outp, namespace, space, dirname, gr, ions, iter, st)
472 write(
message(1),
'(a,i3,a)')
'The calculation converged after ',rdm%iter,
' iterations'
476 write(
message(1),
'(a,i3,a)')
'The calculation did not converge after ', iter-1,
' iterations '
477 write(
message(2),
'(a,es15.5)')
'Relative energy difference between the last two iterations ', rel_ener
478 write(
message(3),
'(a,es15.5)')
'The maximal non-diagonal element of the Hermitian matrix F is ', rdm%maxFO
491 character(len=*),
intent(in) :: dir, fname
493 integer :: iunit, ist
494 real(real64),
allocatable :: photon_number_state (:), ekin_state (:), epot_state (:)
498 safe_allocate(photon_number_state(1:st%nst))
499 safe_allocate(ekin_state(1:st%nst))
500 safe_allocate(epot_state(1:st%nst))
502 if(st%system_grp%is_root())
then
504 iunit =
io_open(trim(dir) //
"/" // trim(fname), namespace, action=
'write')
510 if (rdm%do_basis)
then
511 write(iunit,
'(a)')
'Orbital optimization with [basis set]'
513 write(iunit,
'(a)')
'Orbital optimization with [conjugated gradients]'
518 write(iunit,
'(a)')
'Hartree Fock calculation'
522 if (hm%psolver%is_dressed)
then
523 write(iunit,
'(a)')
'Dressed state calculation'
530 write(iunit,
'(a, i4, a)')
'SCF converged in ', iter,
' iterations'
532 write(iunit,
'(a)')
'SCF *not* converged!'
538 write(iunit,
'(a,1x,f16.12)')
'Sum of occupation numbers:', rdm%occsum
543 if (hm%psolver%is_dressed)
then
544 call calc_photon_number(space, gr, st, hm%psolver%photons, photon_number_state, ekin_state, epot_state)
545 if(st%system_grp%is_root())
then
546 write(iunit,
'(a,1x,f14.12)')
'Total mode occupation:', hm%psolver%photons%number(1)
550 if(st%system_grp%is_root())
then
551 if (rdm%max_iter > 0)
then
552 write(iunit,
'(a)')
'Convergence:'
553 write(iunit,
'(6x, a, es15.8)')
'maxFO = ', rdm%maxFO
554 write(iunit,
'(6x, a, es15.8)')
'rel_ener = ', rel_ener
560 if (st%system_grp%is_root())
then
562 write(iunit,
'(a)')
'Natural occupation numbers:'
563 write(iunit,
'(a4,5x,a12)', advance=
'no')
'#st',
'Occupation'
564 if (.not. rdm%do_basis)
write(iunit,
'(5x,a12)', advance=
'no')
'conv'
565 if (hm%psolver%is_dressed)
write(iunit,
'(3(5x,a12))', advance=
'no')
'Mode Occ.',
'-1/2d^2/dq^2',
'1/2w^2q^2'
570 write(iunit,
'(i4,3x,f14.12)', advance=
'no') ist, st%occ(ist, 1)
571 if (.not. rdm%do_basis)
write(iunit,
'(3x,f14.12)', advance=
'no') rdm%eigens%diff(ist, 1)
572 if (hm%psolver%is_dressed)
then
573 write(iunit,
'(3(3x,f14.12))', advance=
'no') photon_number_state(ist), ekin_state(ist), epot_state(ist)
579 if (st%system_grp%is_root())
then
583 safe_deallocate_a(photon_number_state)
584 safe_deallocate_a(ekin_state)
585 safe_deallocate_a(epot_state)
592 subroutine calc_maxfo (namespace, hm, st, gr, rdm)
594 type(
rdm_t),
intent(inout) :: rdm
595 type(
grid_t),
intent(in) :: gr
599 real(real64),
allocatable :: lambda(:, :), FO(:, :)
604 safe_allocate(lambda(1:st%nst,1:st%nst))
605 safe_allocate(fo(1:st%nst, 1:st%nst))
615 fo(jst, ist) = - (lambda(jst, ist) - lambda(ist ,jst))
618 rdm%maxFO = maxval(abs(fo))
620 safe_deallocate_a(lambda)
621 safe_deallocate_a(fo)
627 subroutine calc_photon_number(space, gr, st, photons, photon_number_state, ekin_state, epot_state)
628 class(
space_t),
intent(in) :: space
629 type(
grid_t),
intent(in) :: gr
632 real(real64),
intent(out) :: photon_number_state(:)
633 real(real64),
intent(out) :: ekin_state(:)
634 real(real64),
intent(out) :: epot_state(:)
636 integer :: ist, dim_photon
637 real(real64) :: q2_exp, laplace_exp
638 real(real64),
allocatable :: psi(:, :), psi_q2(:), dpsidq(:), d2psidq2(:)
643 dim_photon = space%dim
645 safe_allocate(psi(1:gr%np_part, 1))
646 safe_allocate(psi_q2(1:gr%np))
647 safe_allocate(dpsidq(1:gr%np_part))
648 safe_allocate(d2psidq2(1:gr%np))
650 photons%number(1) =
m_zero
658 laplace_exp =
dmf_dotp(gr, psi(:, 1), d2psidq2(:))
659 ekin_state(ist) = -
m_half*laplace_exp
662 psi_q2(1:gr%np) = psi(1:gr%np, 1) * gr%x_t(1:gr%np, dim_photon)**2
663 q2_exp =
dmf_dotp(gr, psi(:, 1), psi_q2(:))
664 epot_state(ist) =
m_half * photons%omega(1)**2 * q2_exp
668 photon_number_state(ist) = -
m_half*laplace_exp / photons%omega(1) +
m_half * photons%omega(1) * q2_exp
669 photon_number_state(ist) = photon_number_state(ist) -
m_half
672 photons%number(1) = photons%number(1) + (photon_number_state(ist) +
m_half)*st%occ(ist, 1)
676 photons%number(1) = photons%number(1) - st%qtot/
m_two
678 safe_deallocate_a(psi)
679 safe_deallocate_a(psi_q2)
680 safe_deallocate_a(dpsidq)
681 safe_deallocate_a(d2psidq2)
692 real(real64),
allocatable :: occin(:, :)
696 safe_allocate(occin(1:st%nst, 1:st%nik))
698 occin(1:st%nst, 1:st%nik) = st%occ(1:st%nst, 1:st%nik)
700 where(occin(:, :) >
m_one) occin(:, :) = st%smear%el_per_state
702 st%occ(:, :) = occin(:, :)
704 safe_deallocate_a(occin)
713 subroutine scf_occ_no(rdm, namespace, gr, hm, space, st, energy)
714 type(
rdm_t),
intent(inout) :: rdm
716 type(
grid_t),
intent(in) :: gr
718 class(
space_t),
intent(in) :: space
720 real(real64),
intent(out) :: energy
726 write(
message(1),
'(a)')
'SKIP Optimization of occupation numbers'
737 rdm%occsum = sum(st%occ(1:st%nst, 1:st%nik))
739 write(
message(1),
'(a4,5x,a12)')
'#st',
'Occupation'
743 write(
message(1),
'(i4,3x,f11.9)') ist, st%occ(ist, 1)
747 write(
message(1),
'(a,1x,f13.9)')
'Sum of occupation numbers', rdm%occsum
755 subroutine scf_occ(rdm, namespace, gr, hm, space, st, energy)
756 type(
rdm_t),
target,
intent(inout) :: rdm
758 type(
grid_t),
intent(in) :: gr
760 class(
space_t),
intent(in) :: space
762 real(real64),
intent(out) :: energy
764 integer :: ist, icycle, ierr
765 real(real64) :: sumgi1, sumgi2, sumgim, mu1, mu2, mum, dinterv, thresh_occ
766 real(real64),
allocatable :: occin(:, :)
767 real(real64),
parameter :: smallocc = 0.00001_real64
768 real(real64),
allocatable :: theta(:)
769 real(real64) :: objective
770 integer,
parameter :: max_cycle = 200
775 write(
message(1),
'(a)')
'Optimization of occupation numbers'
778 safe_allocate(occin(1:st%nst, 1:st%nik))
779 safe_allocate(theta(1:st%nst))
787 thresh_occ = 1e-14_real64
790 occin(1:st%nst, 1:st%nik) = st%occ(1:st%nst, 1:st%nik)
791 where(occin(:, :) < smallocc) occin(:, :) = smallocc
792 where(occin(:, :) > st%smear%el_per_state - smallocc) occin(:, :) = st%smear%el_per_state - smallocc
797 st%occ(:, :) = occin(:, :)
812 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
814 sumgi1 = rdm%occsum - st%qtot
817 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
819 sumgi2 = rdm%occsum - st%qtot
822 do icycle = 1, max_cycle
823 if (sumgi1*sumgi2 <=
m_zero)
exit
830 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
832 sumgi1 = rdm%occsum - st%qtot
839 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
841 sumgi2 = rdm%occsum - st%qtot
849 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.0001_real64, &
851 sumgim = rdm%occsum - st%qtot
853 if (sumgi1*sumgim <
m_zero)
then
863 if (st%occ(ist,1) <= thresh_occ ) st%occ(ist,1) = thresh_occ
866 if (abs(sumgim) < rdm%toler .or. abs((mu1-mu2)*
m_half) < rdm%toler)
exit
871 if (icycle >= 50)
then
872 write(
message(1),
'(a,1x,f11.4)')
'Bisection ended without finding mu, sum of occupation numbers:', rdm%occsum
877 st%occ(ist, 1) = st%smear%el_per_state*
sin(theta(ist)*
m_pi*
m_two)**2
880 objective = objective + rdm%mu*(rdm%occsum - rdm%qtot)
883 write(
message(1),
'(a4,5x,a12)')
'#st',
'Occupation'
887 write(
message(1),
'(i4,3x,f14.12)') ist, st%occ(ist, 1)
891 write(
message(1),
'(a,3x,f11.9)')
'Sum of occupation numbers: ', rdm%occsum
895 safe_deallocate_a(occin)
896 safe_deallocate_a(theta)
904 integer,
intent(in) :: size
905 real(real64),
intent(in) :: theta(size)
906 real(real64),
intent(inout) :: objective
907 integer,
intent(in) :: getgrad
908 real(real64),
intent(inout) :: df(size)
911 real(real64) :: thresh_occ, thresh_theta
912 real(real64),
allocatable :: dE_dn(:),occ(:)
916 assert(
size == rdm_ptr%nst)
918 safe_allocate(de_dn(1:size))
919 safe_allocate(occ(1:size))
925 thresh_occ = 1e-14_real64
930 if (occ(ist) <= thresh_occ ) occ(ist) = thresh_occ
933 rdm_ptr%occsum = sum(occ(1:size))
940 if (occ(ist) <= thresh_occ )
then
946 objective = objective - rdm_ptr%mu*(rdm_ptr%occsum - rdm_ptr%qtot)
948 safe_deallocate_a(de_dn)
949 safe_deallocate_a(occ)
956 integer,
intent(in) :: iter
957 integer,
intent(in) :: size
958 real(real64),
intent(in) :: energy, maxdr, maxdf
959 real(real64),
intent(in) :: theta(size)
969 subroutine scf_orb(rdm, namespace, gr, st, hm, space, energy)
970 type(
rdm_t),
intent(inout) :: rdm
972 type(
grid_t),
intent(in) :: gr
975 class(
space_t),
intent(in) :: space
976 real(real64),
intent(out) :: energy
979 real(real64),
allocatable :: lambda(:, :), fo(:, :)
985 safe_allocate(lambda(1:st%nst,1:st%nst))
986 safe_allocate(fo(1:st%nst, 1:st%nst))
994 if (rdm%iter==1)
then
997 fo(ist, jst) =
m_half*(lambda(ist, jst) + lambda(jst, ist))
998 fo(jst, ist) = fo(ist, jst)
1004 fo(jst, ist) = - ( lambda(jst, ist) - lambda(ist ,jst))
1007 rdm%maxfo = maxval(abs(fo))
1009 fo(ist, ist) = rdm%evalues(ist)
1011 if(abs(fo(jst, ist)) > rdm%scale_f)
then
1012 fo(jst, ist) = rdm%scale_f*fo(jst,ist)/abs(fo(jst, ist))
1014 fo(ist, jst) = fo(jst, ist)
1025 safe_deallocate_a(lambda)
1026 safe_deallocate_a(fo)
1036 subroutine scf_orb_cg(rdm, namespace, space, gr, ions, ext_partners, st, ks, hm, energy)
1037 type(
rdm_t),
intent(inout) :: rdm
1040 type(
grid_t),
intent(in) :: gr
1041 type(
ions_t),
intent(in) :: ions
1044 type(
v_ks_t),
intent(inout) :: ks
1046 real(real64),
intent(out) :: energy
1048 integer :: ik, ist, maxiter
1054 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners)
1055 call hm%update(gr, namespace, space, ext_partners)
1057 rdm%eigens%converged = 0
1058 if(st%system_grp%is_root() .and. .not.
debug%info)
then
1061 do ik = st%d%kpt%start, st%d%kpt%end
1062 rdm%eigens%matvec = 0
1063 maxiter = rdm%eigens%es_maxiter
1064 call deigensolver_cg(namespace, gr, st, hm, rdm%eigens%pre, rdm%eigens%tolerance, maxiter, &
1065 rdm%eigens%converged(ik), ik, rdm%eigens%diff(:, ik), rdm%eigens%energy_change_threshold, &
1066 rdm%eigens%orthogonalize_to_all, rdm%eigens%conjugate_direction)
1068 if (.not. rdm%eigens%folded_spectrum)
then
1070 rdm%eigens%converged(ik) = 0
1072 if(rdm%eigens%diff(ist, ik) < rdm%eigens%tolerance)
then
1073 rdm%eigens%converged(ik) = ist
1081 if(st%system_grp%is_root() .and. .not.
debug%info)
then
1082 write(stdout,
'(1x)')
1087 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners)
1088 call hm%update(gr, namespace, space, ext_partners)
1104 type(
grid_t),
intent(in) :: gr
1105 real(real64),
intent(out) :: lambda(:, :)
1106 type(
rdm_t),
intent(inout) :: rdm
1108 real(real64),
allocatable :: hpsi(:, :), hpsi1(:, :), dpsi(:, :), dpsi1(:, :)
1109 real(real64),
allocatable :: fock(:,:,:), fvec(:)
1110 integer :: ist, iorb, jorb, jst
1117 if (.not. rdm%do_basis)
then
1118 safe_allocate(hpsi(1:gr%np,1:st%d%dim))
1119 safe_allocate(hpsi1(1:gr%np,1:st%d%dim))
1120 safe_allocate(dpsi(1:gr%np_part ,1:st%d%dim))
1121 safe_allocate(dpsi1(1:gr%np_part ,1:st%d%dim))
1127 do jorb = iorb, st%nst
1130 lambda(jorb, iorb) =
dmf_dotp(gr, dpsi1(:,1), hpsi(:,1))
1133 if (iorb /= jorb )
then
1135 lambda(iorb, jorb) =
dmf_dotp(gr, dpsi(:,1), hpsi1(:,1))
1143 safe_allocate(fvec(1:st%nst))
1144 safe_allocate(fock(1:st%nst, 1:st%nst, 1:st%nst))
1150 fock(ist, jst, iorb) = st%occ(iorb, 1)*rdm%eone_int(ist,jst)
1153 fock(ist ,jst, iorb) = fock(ist, jst, iorb) + st%occ(iorb, 1)*st%occ(jorb, 1)*rdm%Coul(ist, jst, jorb) &
1154 -
sqrt(st%occ(iorb, 1))*
sqrt(st%occ(jorb, 1))*rdm%Exch(ist, jst, jorb)
1156 fock(jst, ist, iorb) = fock(ist, jst, iorb)
1165 fvec(ist) = fvec(ist) + fock(ist, jst, jorb)*rdm%vecnat(jst, jorb)
1169 lambda(iorb, jorb) =
m_zero
1171 lambda(iorb, jorb) = lambda(iorb, jorb) + rdm%vecnat(ist, iorb)*fvec(ist)
1178 if (.not. rdm%do_basis)
then
1179 safe_deallocate_a(hpsi)
1180 safe_deallocate_a(hpsi1)
1181 safe_deallocate_a(dpsi)
1182 safe_deallocate_a(dpsi1)
1184 safe_deallocate_a(fvec)
1185 safe_deallocate_a(fock)
1197 real(real64),
intent(in) :: lambda(:, :)
1199 integer :: iorb, jorb, ist
1200 real(real64),
allocatable :: vecnat_new(:, :)
1202 push_sub(assign_eigenfunctions)
1204 safe_allocate(vecnat_new(1:st%nst, 1:st%nst))
1207 vecnat_new(ist, iorb) =
m_zero
1209 vecnat_new(ist , iorb) = vecnat_new(ist, iorb) + rdm%vecnat(ist, jorb)*lambda(jorb, iorb)
1214 rdm%vecnat(:, :) = vecnat_new(:, :)
1216 safe_deallocate_a(vecnat_new)
1218 pop_sub(assign_eigenfunctions)
1225 type(
rdm_t),
intent(in) :: rdm
1226 real(real64),
intent(in) :: occ(:)
1227 real(real64),
intent(out) :: energy
1228 real(real64),
optional,
intent(out) :: dE_dn(:)
1231 real(real64),
allocatable :: V_h(:), V_x(:)
1235 safe_allocate(v_h(1:rdm%nst))
1236 safe_allocate(v_x(1:rdm%nst))
1246 v_h(ist) = v_h(ist) + occ(jst)*rdm%hartree(ist, jst)
1247 v_x(ist) = v_x(ist) -
sqrt(occ(jst))*rdm%exchange(ist, jst)
1249 v_x(ist) = v_x(ist)*
m_half/max(
sqrt(occ(ist)), 1.0e-16_real64)
1254 if (
present(de_dn))
then
1255 de_dn(:) = rdm%eone(:) + v_h(:) + v_x(:)
1260 energy = energy + occ(ist)*rdm%eone(ist) &
1261 +
m_half*occ(ist)*v_h(ist) &
1265 safe_deallocate_a(v_h)
1266 safe_deallocate_a(v_x)
1274 type(
rdm_t),
intent(inout) :: rdm
1278 type(
grid_t),
intent(in) :: gr
1279 class(
space_t),
intent(in) :: space
1282 real(real64),
allocatable :: hpsi(:, :), rho1(:), rho(:), dpsi(:, :), dpsi2(:, :)
1283 real(real64),
allocatable :: v_ij(:,:,:,:,:)
1287 integer :: ist, jst, nspin_, iorb, jorb
1292 nspin_ = min(st%d%nspin, 2)
1294 if (.not. rdm%do_basis)
then
1295 safe_allocate(hpsi(1:gr%np, 1:st%d%dim))
1296 safe_allocate(rho1(1:gr%np))
1297 safe_allocate(rho(1:gr%np))
1298 safe_allocate(dpsi(1:gr%np_part, 1:st%d%dim))
1299 safe_allocate(dpsi2(1:gr%np, 1:st%d%dim))
1300 safe_allocate(v_ij(1:gr%np, 1:st%nst, 1:st%nst, 1:st%nik, 1:st%nik))
1314 rdm%eone(ist) =
dmf_dotp(gr, dpsi(:, 1), hpsi(:, 1))
1328 rho1(1:gr%np) = dpsi(1:gr%np, 1)**2
1330 do jst = ist, st%nst
1331 rdm%hartree(ist, jst) =
dmf_dotp(gr, rho1, v_ij(:,jst, jst, 1, 1))
1332 rdm%hartree(jst, ist) = rdm%hartree(ist, jst)
1334 rho(1:gr%np) = dpsi2(1:gr%np, 1)*dpsi(1:gr%np, 1)
1335 rdm%exchange(ist, jst) =
dmf_dotp(gr, rho, v_ij(:, ist, jst, 1, 1))
1336 rdm%exchange(jst, ist) = rdm%exchange(ist, jst)
1341 safe_deallocate_a(hpsi)
1342 safe_deallocate_a(rho)
1343 safe_deallocate_a(rho1)
1344 safe_deallocate_a(dpsi)
1345 safe_deallocate_a(dpsi2)
1346 safe_deallocate_a(v_ij)
1354 dd = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1355 rdm%eone(iorb) = rdm%eone(iorb) + dd*rdm%eone_int(ist, jst)
1362 rdm%hartree(iorb ,jorb) =
m_zero
1363 rdm%exchange(iorb,jorb) =
m_zero
1366 dd = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1367 rdm%hartree(iorb ,jorb) = rdm%hartree(iorb ,jorb)+rdm%Coul(ist,jst, jorb)*dd
1368 rdm%exchange(iorb ,jorb) = rdm%exchange(iorb ,jorb)+rdm%Exch(ist,jst, jorb)*dd
1371 rdm%hartree(jorb, iorb) = rdm%hartree(iorb, jorb)
1372 rdm%exchange(jorb, iorb) = rdm%exchange(iorb, jorb)
1383 type(
rdm_t),
intent(inout) :: rdm
1387 class(
mesh_t),
intent(in) :: mesh
1389 real(real64),
allocatable :: hpsi(:, :)
1390 real(real64),
allocatable :: dpsi(:, :), dpsi2(:, :)
1395 safe_allocate(dpsi(1:mesh%np_part, 1:st%d%dim))
1396 safe_allocate(dpsi2(1:mesh%np, 1:st%d%dim))
1397 safe_allocate(hpsi(1:mesh%np, 1:st%d%dim))
1402 do jst = ist, st%nst
1408 rdm%eone_int(jst, ist) =
dmf_dotp(mesh, dpsi2(:, 1), hpsi(:, 1))
1409 rdm%eone_int(ist, jst) = rdm%eone_int(jst, ist)
1413 safe_deallocate_a(hpsi)
1414 safe_deallocate_a(dpsi)
1415 safe_deallocate_a(dpsi2)
1423 type(
rdm_t),
intent(inout) :: rdm
1425 integer :: ist, jst, kst, lst, iorb, icount
1426 logical :: inv_pairs
1427 real(real64) :: two_int, wij, wik, wil, wjk, wjl, wkl
1428 real(real64),
allocatable :: dm(:,:,:)
1432 safe_allocate(dm(1:rdm%nst, 1:rdm%nst, 1:rdm%nst))
1438 do iorb = 1, rdm%nst
1441 dm(ist, jst, iorb) = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1442 dm(jst, ist, iorb) = dm(ist, jst, iorb)
1447 do icount = 1, rdm%n_twoint
1449 ist = rdm%i_index(1,icount)
1450 jst = rdm%j_index(1,icount)
1451 kst = rdm%k_index(1,icount)
1452 lst = rdm%l_index(1,icount)
1454 two_int = rdm%twoint(icount)
1468 if(ist == kst .and. jst /= lst)
then
1473 if(ist == lst .and. jst /= kst)
then
1478 if(jst == kst .and. ist /= lst)
then
1483 if(jst == lst .and. ist /= kst)
then
1489 inv_pairs = (ist /= kst .or. jst /= lst)
1491 do iorb = 1, rdm%nst
1494 rdm%Coul(ist, jst, iorb) = rdm%Coul(ist, jst, iorb) + dm(kst, lst, iorb)*wkl*two_int
1495 if (inv_pairs) rdm%Coul(kst, lst, iorb) = rdm%Coul(kst, lst, iorb) + dm(ist, jst, iorb)*wij*two_int
1499 rdm%Exch(ist, kst, iorb) = rdm%Exch(ist, kst, iorb) + two_int*dm(jst, lst, iorb)*wik
1500 if (kst /= lst)
then
1501 rdm%Exch(ist, lst, iorb) = rdm%Exch(ist, lst, iorb) + two_int*dm(jst, kst, iorb)*wil
1503 if (ist /= jst)
then
1505 rdm%Exch(jst, kst, iorb) = rdm%Exch(jst, kst, iorb) + two_int*dm(ist, lst, iorb)*wjk
1507 if (inv_pairs) rdm%Exch(kst, jst, iorb) = rdm%Exch(kst, jst, iorb) + two_int*dm(ist, lst, iorb)
1510 if (ist /=jst .and. kst /= lst)
then
1511 if (jst >= lst)
then
1512 rdm%Exch(jst, lst, iorb) = rdm%Exch(jst, lst, iorb) + two_int*dm(ist, kst, iorb)*wjl
1514 if (inv_pairs) rdm%Exch(lst, jst, iorb) = rdm%Exch(lst, jst, iorb) + two_int*dm(ist, kst, iorb)
1524 rdm%Coul(jst, ist, iorb) = rdm%Coul(ist, jst, iorb)
1525 rdm%Exch(jst, ist, iorb) = rdm%Exch(ist, jst, iorb)
1530 safe_deallocate_a(dm)
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.