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))
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)
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))
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)
546 write(iunit,
'(a,1x,f14.12)')
'Total mode occupation:', hm%psolver%photons%number(1)
551 if (rdm%max_iter > 0)
then
552 write(iunit,
'(a)')
'Convergence:'
553 write(iunit,
'(6x, a, es15.8,a,es15.8,a)')
'maxFO = ', rdm%maxFO
554 write(iunit,
'(6x, a, es15.8,a,es15.8,a)')
'rel_ener = ', rel_ener
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)
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(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
774 write(
message(1),
'(a)')
'Optimization of occupation numbers'
777 safe_allocate(occin(1:st%nst, 1:st%nik))
778 safe_allocate(theta(1:st%nst))
786 thresh_occ = 1e-14_real64
789 occin(1:st%nst, 1:st%nik) = st%occ(1:st%nst, 1:st%nik)
790 where(occin(:, :) < smallocc) occin(:, :) = smallocc
791 where(occin(:, :) > st%smear%el_per_state - smallocc) occin(:, :) = st%smear%el_per_state - smallocc
796 st%occ(:, :) = occin(:, :)
811 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
813 sumgi1 = rdm%occsum - st%qtot
816 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
818 sumgi2 = rdm%occsum - st%qtot
821 do while (sumgi1*sumgi2 >
m_zero)
828 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
830 sumgi1 = rdm%occsum - st%qtot
837 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
839 sumgi2 = rdm%occsum - st%qtot
847 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.0001_real64, &
849 sumgim = rdm%occsum - st%qtot
851 if (sumgi1*sumgim <
m_zero)
then
861 if (st%occ(ist,1) <= thresh_occ ) st%occ(ist,1) = thresh_occ
864 if (abs(sumgim) < rdm%toler .or. abs((mu1-mu2)*
m_half) < rdm%toler)
exit
869 if (icycle >= 50)
then
870 write(
message(1),
'(a,1x,f11.4)')
'Bisection ended without finding mu, sum of occupation numbers:', rdm%occsum
875 st%occ(ist, 1) = st%smear%el_per_state*
sin(theta(ist)*
m_pi*
m_two)**2
878 objective = objective + rdm%mu*(rdm%occsum - rdm%qtot)
881 write(
message(1),
'(a4,5x,a12)')
'#st',
'Occupation'
885 write(
message(1),
'(i4,3x,f14.12)') ist, st%occ(ist, 1)
889 write(
message(1),
'(a,3x,f11.9)')
'Sum of occupation numbers: ', rdm%occsum
893 safe_deallocate_a(occin)
894 safe_deallocate_a(theta)
902 integer,
intent(in) :: size
903 real(real64),
intent(in) :: theta(size)
904 real(real64),
intent(inout) :: objective
905 integer,
intent(in) :: getgrad
906 real(real64),
intent(inout) :: df(size)
909 real(real64) :: thresh_occ, thresh_theta
910 real(real64),
allocatable :: dE_dn(:),occ(:)
914 assert(
size == rdm_ptr%nst)
916 safe_allocate(de_dn(1:size))
917 safe_allocate(occ(1:size))
923 thresh_occ = 1e-14_real64
928 if (occ(ist) <= thresh_occ ) occ(ist) = thresh_occ
931 rdm_ptr%occsum = sum(occ(1:size))
938 if (occ(ist) <= thresh_occ )
then
944 objective = objective - rdm_ptr%mu*(rdm_ptr%occsum - rdm_ptr%qtot)
946 safe_deallocate_a(de_dn)
947 safe_deallocate_a(occ)
954 integer,
intent(in) :: iter
955 integer,
intent(in) :: size
956 real(real64),
intent(in) :: energy, maxdr, maxdf
957 real(real64),
intent(in) :: theta(size)
967 subroutine scf_orb(rdm, namespace, gr, st, hm, space, energy)
968 type(
rdm_t),
intent(inout) :: rdm
970 type(
grid_t),
intent(in) :: gr
973 class(
space_t),
intent(in) :: space
974 real(real64),
intent(out) :: energy
977 real(real64),
allocatable :: lambda(:, :), fo(:, :)
983 safe_allocate(lambda(1:st%nst,1:st%nst))
984 safe_allocate(fo(1:st%nst, 1:st%nst))
992 if (rdm%iter==1)
then
995 fo(ist, jst) =
m_half*(lambda(ist, jst) + lambda(jst, ist))
996 fo(jst, ist) = fo(ist, jst)
1002 fo(jst, ist) = - ( lambda(jst, ist) - lambda(ist ,jst))
1005 rdm%maxfo = maxval(abs(fo))
1007 fo(ist, ist) = rdm%evalues(ist)
1009 if(abs(fo(jst, ist)) > rdm%scale_f)
then
1010 fo(jst, ist) = rdm%scale_f*fo(jst,ist)/abs(fo(jst, ist))
1012 fo(ist, jst) = fo(jst, ist)
1023 safe_deallocate_a(lambda)
1024 safe_deallocate_a(fo)
1034 subroutine scf_orb_cg(rdm, namespace, space, gr, ions, ext_partners, st, ks, hm, energy)
1035 type(
rdm_t),
intent(inout) :: rdm
1038 type(
grid_t),
intent(in) :: gr
1039 type(
ions_t),
intent(in) :: ions
1042 type(
v_ks_t),
intent(inout) :: ks
1044 real(real64),
intent(out) :: energy
1046 integer :: ik, ist, maxiter
1052 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners)
1053 call hm%update(gr, namespace, space, ext_partners)
1055 rdm%eigens%converged = 0
1059 do ik = st%d%kpt%start, st%d%kpt%end
1060 rdm%eigens%matvec = 0
1061 maxiter = rdm%eigens%es_maxiter
1062 call deigensolver_cg(namespace, gr, st, hm, rdm%eigens%pre, rdm%eigens%tolerance, maxiter, &
1063 rdm%eigens%converged(ik), ik, rdm%eigens%diff(:, ik), rdm%eigens%energy_change_threshold, &
1064 rdm%eigens%orthogonalize_to_all, rdm%eigens%conjugate_direction)
1066 if (.not. rdm%eigens%folded_spectrum)
then
1068 rdm%eigens%converged(ik) = 0
1070 if(rdm%eigens%diff(ist, ik) < rdm%eigens%tolerance)
then
1071 rdm%eigens%converged(ik) = ist
1080 write(stdout,
'(1x)')
1085 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners)
1086 call hm%update(gr, namespace, space, ext_partners)
1102 type(
grid_t),
intent(in) :: gr
1103 real(real64),
intent(out) :: lambda(:, :)
1104 type(
rdm_t),
intent(inout) :: rdm
1106 real(real64),
allocatable :: hpsi(:, :), hpsi1(:, :), dpsi(:, :), dpsi1(:, :)
1107 real(real64),
allocatable :: fock(:,:,:), fvec(:)
1108 integer :: ist, iorb, jorb, jst
1115 if (.not. rdm%do_basis)
then
1116 safe_allocate(hpsi(1:gr%np,1:st%d%dim))
1117 safe_allocate(hpsi1(1:gr%np,1:st%d%dim))
1118 safe_allocate(dpsi(1:gr%np_part ,1:st%d%dim))
1119 safe_allocate(dpsi1(1:gr%np_part ,1:st%d%dim))
1125 do jorb = iorb, st%nst
1128 lambda(jorb, iorb) =
dmf_dotp(gr, dpsi1(:,1), hpsi(:,1))
1131 if (.not. iorb == jorb )
then
1133 lambda(iorb, jorb) =
dmf_dotp(gr, dpsi(:,1), hpsi1(:,1))
1141 safe_allocate(fvec(1:st%nst))
1142 safe_allocate(fock(1:st%nst, 1:st%nst, 1:st%nst))
1148 fock(ist, jst, iorb) = st%occ(iorb, 1)*rdm%eone_int(ist,jst)
1151 fock(ist ,jst, iorb) = fock(ist, jst, iorb) + st%occ(iorb, 1)*st%occ(jorb, 1)*rdm%Coul(ist, jst, jorb) &
1152 -
sqrt(st%occ(iorb, 1))*
sqrt(st%occ(jorb, 1))*rdm%Exch(ist, jst, jorb)
1154 fock(jst, ist, iorb) = fock(ist, jst, iorb)
1163 fvec(ist) = fvec(ist) + fock(ist, jst, jorb)*rdm%vecnat(jst, jorb)
1167 lambda(iorb, jorb) =
m_zero
1169 lambda(iorb, jorb) = lambda(iorb, jorb) + rdm%vecnat(ist, iorb)*fvec(ist)
1176 if (.not. rdm%do_basis)
then
1177 safe_deallocate_a(hpsi)
1178 safe_deallocate_a(hpsi1)
1179 safe_deallocate_a(dpsi)
1180 safe_deallocate_a(dpsi1)
1182 safe_deallocate_a(fvec)
1183 safe_deallocate_a(fock)
1195 real(real64),
intent(in) :: lambda(:, :)
1197 integer :: iorb, jorb, ist
1198 real(real64),
allocatable :: vecnat_new(:, :)
1200 push_sub(assign_eigenfunctions)
1202 safe_allocate(vecnat_new(1:st%nst, 1:st%nst))
1205 vecnat_new(ist, iorb) =
m_zero
1207 vecnat_new(ist , iorb) = vecnat_new(ist, iorb) + rdm%vecnat(ist, jorb)*lambda(jorb, iorb)
1212 rdm%vecnat(:, :) = vecnat_new(:, :)
1214 safe_deallocate_a(vecnat_new)
1216 pop_sub(assign_eigenfunctions)
1223 type(
rdm_t),
intent(in) :: rdm
1224 real(real64),
intent(in) :: occ(:)
1225 real(real64),
intent(out) :: energy
1226 real(real64),
optional,
intent(out) :: dE_dn(:)
1229 real(real64),
allocatable :: V_h(:), V_x(:)
1233 safe_allocate(v_h(1:rdm%nst))
1234 safe_allocate(v_x(1:rdm%nst))
1244 v_h(ist) = v_h(ist) + occ(jst)*rdm%hartree(ist, jst)
1245 v_x(ist) = v_x(ist) -
sqrt(occ(jst))*rdm%exchange(ist, jst)
1247 v_x(ist) = v_x(ist)*
m_half/max(
sqrt(occ(ist)), 1.0e-16_real64)
1252 if (
present(de_dn))
then
1253 de_dn(:) = rdm%eone(:) + v_h(:) + v_x(:)
1258 energy = energy + occ(ist)*rdm%eone(ist) &
1259 +
m_half*occ(ist)*v_h(ist) &
1263 safe_deallocate_a(v_h)
1264 safe_deallocate_a(v_x)
1272 type(
rdm_t),
intent(inout) :: rdm
1276 type(
grid_t),
intent(in) :: gr
1277 class(
space_t),
intent(in) :: space
1280 real(real64),
allocatable :: hpsi(:, :), rho1(:), rho(:), dpsi(:, :), dpsi2(:, :)
1281 real(real64),
allocatable :: v_ij(:,:,:,:,:)
1285 integer :: ist, jst, nspin_, iorb, jorb
1290 nspin_ = min(st%d%nspin, 2)
1292 if (rdm%do_basis.eqv..false.)
then
1293 safe_allocate(hpsi(1:gr%np, 1:st%d%dim))
1294 safe_allocate(rho1(1:gr%np))
1295 safe_allocate(rho(1:gr%np))
1296 safe_allocate(dpsi(1:gr%np_part, 1:st%d%dim))
1297 safe_allocate(dpsi2(1:gr%np, 1:st%d%dim))
1298 safe_allocate(v_ij(1:gr%np, 1:st%nst, 1:st%nst, 1:st%nik, 1:st%nik))
1312 rdm%eone(ist) =
dmf_dotp(gr, dpsi(:, 1), hpsi(:, 1))
1326 rho1(1:gr%np) = dpsi(1:gr%np, 1)**2
1328 do jst = ist, st%nst
1329 rdm%hartree(ist, jst) =
dmf_dotp(gr, rho1, v_ij(:,jst, jst, 1, 1))
1330 rdm%hartree(jst, ist) = rdm%hartree(ist, jst)
1332 rho(1:gr%np) = dpsi2(1:gr%np, 1)*dpsi(1:gr%np, 1)
1333 rdm%exchange(ist, jst) =
dmf_dotp(gr, rho, v_ij(:, ist, jst, 1, 1))
1334 rdm%exchange(jst, ist) = rdm%exchange(ist, jst)
1339 safe_deallocate_a(hpsi)
1340 safe_deallocate_a(rho)
1341 safe_deallocate_a(rho1)
1342 safe_deallocate_a(dpsi)
1343 safe_deallocate_a(dpsi2)
1344 safe_deallocate_a(v_ij)
1352 dd = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1353 rdm%eone(iorb) = rdm%eone(iorb) + dd*rdm%eone_int(ist, jst)
1360 rdm%hartree(iorb ,jorb) =
m_zero
1361 rdm%exchange(iorb,jorb) =
m_zero
1364 dd = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1365 rdm%hartree(iorb ,jorb) = rdm%hartree(iorb ,jorb)+rdm%Coul(ist,jst, jorb)*dd
1366 rdm%exchange(iorb ,jorb) = rdm%exchange(iorb ,jorb)+rdm%Exch(ist,jst, jorb)*dd
1369 rdm%hartree(jorb, iorb) = rdm%hartree(iorb, jorb)
1370 rdm%exchange(jorb, iorb) = rdm%exchange(iorb, jorb)
1381 type(
rdm_t),
intent(inout) :: rdm
1385 class(
mesh_t),
intent(in) :: mesh
1387 real(real64),
allocatable :: hpsi(:, :)
1388 real(real64),
allocatable :: dpsi(:, :), dpsi2(:, :)
1393 safe_allocate(dpsi(1:mesh%np_part, 1:st%d%dim))
1394 safe_allocate(dpsi2(1:mesh%np, 1:st%d%dim))
1395 safe_allocate(hpsi(1:mesh%np, 1:st%d%dim))
1400 do jst = ist, st%nst
1406 rdm%eone_int(jst, ist) =
dmf_dotp(mesh, dpsi2(:, 1), hpsi(:, 1))
1407 rdm%eone_int(ist, jst) = rdm%eone_int(jst, ist)
1411 safe_deallocate_a(hpsi)
1412 safe_deallocate_a(dpsi)
1413 safe_deallocate_a(dpsi2)
1421 type(
rdm_t),
intent(inout) :: rdm
1423 integer :: ist, jst, kst, lst, iorb, icount
1424 logical :: inv_pairs
1425 real(real64) :: two_int, wij, wik, wil, wjk, wjl, wkl
1426 real(real64),
allocatable :: dm(:,:,:)
1430 safe_allocate(dm(1:rdm%nst, 1:rdm%nst, 1:rdm%nst))
1436 do iorb = 1, rdm%nst
1439 dm(ist, jst, iorb) = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1440 dm(jst, ist, iorb) = dm(ist, jst, iorb)
1445 do icount = 1, rdm%n_twoint
1447 ist = rdm%i_index(1,icount)
1448 jst = rdm%j_index(1,icount)
1449 kst = rdm%k_index(1,icount)
1450 lst = rdm%l_index(1,icount)
1452 two_int = rdm%twoint(icount)
1466 if(ist == kst .and. jst /= lst)
then
1471 if(ist == lst .and. jst /= kst)
then
1476 if(jst == kst .and. ist /= lst)
then
1481 if(jst == lst .and. ist /= kst)
then
1487 inv_pairs = (ist /= kst .or. jst /= lst)
1489 do iorb = 1, rdm%nst
1492 rdm%Coul(ist, jst, iorb) = rdm%Coul(ist, jst, iorb) + dm(kst, lst, iorb)*wkl*two_int
1493 if (inv_pairs) rdm%Coul(kst, lst, iorb) = rdm%Coul(kst, lst, iorb) + dm(ist, jst, iorb)*wij*two_int
1497 rdm%Exch(ist, kst, iorb) = rdm%Exch(ist, kst, iorb) + two_int*dm(jst, lst, iorb)*wik
1498 if (kst /= lst)
then
1499 rdm%Exch(ist, lst, iorb) = rdm%Exch(ist, lst, iorb) + two_int*dm(jst, kst, iorb)*wil
1501 if (ist /= jst)
then
1503 rdm%Exch(jst, kst, iorb) = rdm%Exch(jst, kst, iorb) + two_int*dm(ist, lst, iorb)*wjk
1505 if (inv_pairs) rdm%Exch(kst, jst, iorb) = rdm%Exch(kst, jst, iorb) + two_int*dm(ist, lst, iorb)
1508 if (ist /=jst .and. kst /= lst)
then
1509 if (jst >= lst)
then
1510 rdm%Exch(jst, lst, iorb) = rdm%Exch(jst, lst, iorb) + two_int*dm(ist, kst, iorb)*wjl
1512 if (inv_pairs) rdm%Exch(lst, jst, iorb) = rdm%Exch(lst, jst, iorb) + two_int*dm(ist, kst, iorb)
1522 rdm%Coul(jst, ist, iorb) = rdm%Coul(ist, jst, iorb)
1523 rdm%Exch(jst, ist, iorb) = rdm%Exch(ist, jst, iorb)
1528 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)
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 contains some common usage patterns of MPI routines.
type(mpi_grp_t), public mpi_world
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.