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
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
663 psi_q2(1:gr%np) = psi(1:gr%np, 1) * gr%x_t(1:gr%np, dim_photon)**2
664 q2_exp =
dmf_dotp(gr, psi(:, 1), psi_q2(:))
665 epot_state(ist) =
m_half * photons%omega(1)**2 * q2_exp
669 photon_number_state(ist) = -
m_half*laplace_exp / photons%omega(1) +
m_half * photons%omega(1) * q2_exp
670 photon_number_state(ist) = photon_number_state(ist) -
m_half
673 photons%number(1) = photons%number(1) + (photon_number_state(ist) +
m_half)*st%occ(ist, 1)
677 photons%number(1) = photons%number(1) - st%qtot/
m_two
679 safe_deallocate_a(psi)
680 safe_deallocate_a(psi_q2)
681 safe_deallocate_a(dpsidq)
682 safe_deallocate_a(d2psidq2)
693 real(real64),
allocatable :: occin(:, :)
697 safe_allocate(occin(1:st%nst, 1:st%nik))
699 occin(1:st%nst, 1:st%nik) = st%occ(1:st%nst, 1:st%nik)
701 where(occin(:, :) >
m_one) occin(:, :) = st%smear%el_per_state
703 st%occ(:, :) = occin(:, :)
705 safe_deallocate_a(occin)
714 subroutine scf_occ_no(rdm, namespace, gr, hm, space, st, energy)
715 type(
rdm_t),
intent(inout) :: rdm
717 type(
grid_t),
intent(in) :: gr
719 class(
space_t),
intent(in) :: space
721 real(real64),
intent(out) :: energy
727 write(
message(1),
'(a)')
'SKIP Optimization of occupation numbers'
738 rdm%occsum = sum(st%occ(1:st%nst, 1:st%nik))
740 write(
message(1),
'(a4,5x,a12)')
'#st',
'Occupation'
744 write(
message(1),
'(i4,3x,f11.9)') ist, st%occ(ist, 1)
748 write(
message(1),
'(a,1x,f13.9)')
'Sum of occupation numbers', rdm%occsum
756 subroutine scf_occ(rdm, namespace, gr, hm, space, st, energy)
757 type(
rdm_t),
target,
intent(inout) :: rdm
759 type(
grid_t),
intent(in) :: gr
761 class(
space_t),
intent(in) :: space
763 real(real64),
intent(out) :: energy
765 integer :: ist, icycle, ierr
766 real(real64) :: sumgi1, sumgi2, sumgim, mu1, mu2, mum, dinterv, thresh_occ
767 real(real64),
allocatable :: occin(:, :)
768 real(real64),
parameter :: smallocc = 0.00001_real64
769 real(real64),
allocatable :: theta(:)
770 real(real64) :: objective
771 integer,
parameter :: max_cycle = 200
776 write(
message(1),
'(a)')
'Optimization of occupation numbers'
779 safe_allocate(occin(1:st%nst, 1:st%nik))
780 safe_allocate(theta(1:st%nst))
788 thresh_occ = 1e-14_real64
791 occin(1:st%nst, 1:st%nik) = st%occ(1:st%nst, 1:st%nik)
792 where(occin(:, :) < smallocc) occin(:, :) = smallocc
793 where(occin(:, :) > st%smear%el_per_state - smallocc) occin(:, :) = st%smear%el_per_state - smallocc
798 st%occ(:, :) = occin(:, :)
813 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
815 sumgi1 = rdm%occsum - st%qtot
818 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
820 sumgi2 = rdm%occsum - st%qtot
823 do icycle = 1, max_cycle
824 if (sumgi1*sumgi2 <=
m_zero)
exit
831 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
833 sumgi1 = rdm%occsum - st%qtot
840 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.01_real64, &
842 sumgi2 = rdm%occsum - st%qtot
850 call minimize_multidim(
minmethod_bfgs, st%nst, theta, 0.05_real64, 0.0001_real64, &
852 sumgim = rdm%occsum - st%qtot
854 if (sumgi1*sumgim <
m_zero)
then
864 if (st%occ(ist,1) <= thresh_occ ) st%occ(ist,1) = thresh_occ
867 if (abs(sumgim) < rdm%toler .or. abs((mu1-mu2)*
m_half) < rdm%toler)
exit
872 if (icycle >= 50)
then
873 write(
message(1),
'(a,1x,f11.4)')
'Bisection ended without finding mu, sum of occupation numbers:', rdm%occsum
878 st%occ(ist, 1) = st%smear%el_per_state*
sin(theta(ist)*
m_pi*
m_two)**2
881 objective = objective + rdm%mu*(rdm%occsum - rdm%qtot)
884 write(
message(1),
'(a4,5x,a12)')
'#st',
'Occupation'
888 write(
message(1),
'(i4,3x,f14.12)') ist, st%occ(ist, 1)
892 write(
message(1),
'(a,3x,f11.9)')
'Sum of occupation numbers: ', rdm%occsum
896 safe_deallocate_a(occin)
897 safe_deallocate_a(theta)
905 integer,
intent(in) :: size
906 real(real64),
intent(in) :: theta(size)
907 real(real64),
intent(inout) :: objective
908 integer,
intent(in) :: getgrad
909 real(real64),
intent(inout) :: df(size)
912 real(real64) :: thresh_occ, thresh_theta
913 real(real64),
allocatable :: dE_dn(:),occ(:)
917 assert(
size == rdm_ptr%nst)
919 safe_allocate(de_dn(1:size))
920 safe_allocate(occ(1:size))
926 thresh_occ = 1e-14_real64
931 if (occ(ist) <= thresh_occ ) occ(ist) = thresh_occ
934 rdm_ptr%occsum = sum(occ(1:size))
941 if (occ(ist) <= thresh_occ )
then
947 objective = objective - rdm_ptr%mu*(rdm_ptr%occsum - rdm_ptr%qtot)
949 safe_deallocate_a(de_dn)
950 safe_deallocate_a(occ)
957 integer,
intent(in) :: iter
958 integer,
intent(in) :: size
959 real(real64),
intent(in) :: energy, maxdr, maxdf
960 real(real64),
intent(in) :: theta(size)
970 subroutine scf_orb(rdm, namespace, gr, st, hm, space, energy)
971 type(
rdm_t),
intent(inout) :: rdm
973 type(
grid_t),
intent(in) :: gr
976 class(
space_t),
intent(in) :: space
977 real(real64),
intent(out) :: energy
980 real(real64),
allocatable :: lambda(:, :), fo(:, :)
986 safe_allocate(lambda(1:st%nst,1:st%nst))
987 safe_allocate(fo(1:st%nst, 1:st%nst))
995 if (rdm%iter==1)
then
998 fo(ist, jst) =
m_half*(lambda(ist, jst) + lambda(jst, ist))
999 fo(jst, ist) = fo(ist, jst)
1005 fo(jst, ist) = - ( lambda(jst, ist) - lambda(ist ,jst))
1008 rdm%maxfo = maxval(abs(fo))
1010 fo(ist, ist) = rdm%evalues(ist)
1012 if(abs(fo(jst, ist)) > rdm%scale_f)
then
1013 fo(jst, ist) = rdm%scale_f*fo(jst,ist)/abs(fo(jst, ist))
1015 fo(ist, jst) = fo(jst, ist)
1026 safe_deallocate_a(lambda)
1027 safe_deallocate_a(fo)
1037 subroutine scf_orb_cg(rdm, namespace, space, gr, ions, ext_partners, st, ks, hm, energy)
1038 type(
rdm_t),
intent(inout) :: rdm
1041 type(
grid_t),
intent(in) :: gr
1042 type(
ions_t),
intent(in) :: ions
1045 type(
v_ks_t),
intent(inout) :: ks
1047 real(real64),
intent(out) :: energy
1049 integer :: ik, ist, maxiter
1055 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners)
1056 call hm%update(gr, namespace, space, ext_partners)
1058 rdm%eigens%converged = 0
1059 if(st%system_grp%is_root() .and. .not.
debug%info)
then
1062 do ik = st%d%kpt%start, st%d%kpt%end
1063 rdm%eigens%matvec = 0
1064 maxiter = rdm%eigens%es_maxiter
1065 call deigensolver_cg(namespace, gr, st, hm, rdm%eigens%pre, rdm%eigens%tolerance, maxiter, &
1066 rdm%eigens%converged(ik), ik, rdm%eigens%diff(:, ik), rdm%eigens%energy_change_threshold, &
1067 rdm%eigens%orthogonalize_to_all, rdm%eigens%conjugate_direction)
1069 if (.not. rdm%eigens%folded_spectrum)
then
1071 rdm%eigens%converged(ik) = 0
1073 if(rdm%eigens%diff(ist, ik) < rdm%eigens%tolerance)
then
1074 rdm%eigens%converged(ik) = ist
1082 if(st%system_grp%is_root() .and. .not.
debug%info)
then
1083 write(stdout,
'(1x)')
1088 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners)
1089 call hm%update(gr, namespace, space, ext_partners)
1105 type(
grid_t),
intent(in) :: gr
1106 real(real64),
intent(out) :: lambda(:, :)
1107 type(
rdm_t),
intent(inout) :: rdm
1109 real(real64),
allocatable :: hpsi(:, :), hpsi1(:, :), dpsi(:, :), dpsi1(:, :)
1110 real(real64),
allocatable :: fock(:,:,:), fvec(:)
1111 integer :: ist, iorb, jorb, jst
1118 if (.not. rdm%do_basis)
then
1119 safe_allocate(hpsi(1:gr%np,1:st%d%dim))
1120 safe_allocate(hpsi1(1:gr%np,1:st%d%dim))
1121 safe_allocate(dpsi(1:gr%np_part ,1:st%d%dim))
1122 safe_allocate(dpsi1(1:gr%np_part ,1:st%d%dim))
1128 do jorb = iorb, st%nst
1131 lambda(jorb, iorb) =
dmf_dotp(gr, dpsi1(:,1), hpsi(:,1))
1134 if (iorb /= jorb )
then
1136 lambda(iorb, jorb) =
dmf_dotp(gr, dpsi(:,1), hpsi1(:,1))
1144 safe_allocate(fvec(1:st%nst))
1145 safe_allocate(fock(1:st%nst, 1:st%nst, 1:st%nst))
1151 fock(ist, jst, iorb) = st%occ(iorb, 1)*rdm%eone_int(ist,jst)
1154 fock(ist ,jst, iorb) = fock(ist, jst, iorb) + st%occ(iorb, 1)*st%occ(jorb, 1)*rdm%Coul(ist, jst, jorb) &
1155 -
sqrt(st%occ(iorb, 1))*
sqrt(st%occ(jorb, 1))*rdm%Exch(ist, jst, jorb)
1157 fock(jst, ist, iorb) = fock(ist, jst, iorb)
1166 fvec(ist) = fvec(ist) + fock(ist, jst, jorb)*rdm%vecnat(jst, jorb)
1170 lambda(iorb, jorb) =
m_zero
1172 lambda(iorb, jorb) = lambda(iorb, jorb) + rdm%vecnat(ist, iorb)*fvec(ist)
1179 if (.not. rdm%do_basis)
then
1180 safe_deallocate_a(hpsi)
1181 safe_deallocate_a(hpsi1)
1182 safe_deallocate_a(dpsi)
1183 safe_deallocate_a(dpsi1)
1185 safe_deallocate_a(fvec)
1186 safe_deallocate_a(fock)
1198 real(real64),
intent(in) :: lambda(:, :)
1200 integer :: iorb, jorb, ist
1201 real(real64),
allocatable :: vecnat_new(:, :)
1203 push_sub(assign_eigenfunctions)
1205 safe_allocate(vecnat_new(1:st%nst, 1:st%nst))
1208 vecnat_new(ist, iorb) =
m_zero
1210 vecnat_new(ist , iorb) = vecnat_new(ist, iorb) + rdm%vecnat(ist, jorb)*lambda(jorb, iorb)
1215 rdm%vecnat(:, :) = vecnat_new(:, :)
1217 safe_deallocate_a(vecnat_new)
1219 pop_sub(assign_eigenfunctions)
1226 type(
rdm_t),
intent(in) :: rdm
1227 real(real64),
intent(in) :: occ(:)
1228 real(real64),
intent(out) :: energy
1229 real(real64),
optional,
intent(out) :: dE_dn(:)
1232 real(real64),
allocatable :: V_h(:), V_x(:)
1236 safe_allocate(v_h(1:rdm%nst))
1237 safe_allocate(v_x(1:rdm%nst))
1247 v_h(ist) = v_h(ist) + occ(jst)*rdm%hartree(ist, jst)
1248 v_x(ist) = v_x(ist) -
sqrt(occ(jst))*rdm%exchange(ist, jst)
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(v_h)
1267 safe_deallocate_a(v_x)
1275 type(
rdm_t),
intent(inout) :: rdm
1279 type(
grid_t),
intent(in) :: gr
1280 class(
space_t),
intent(in) :: space
1283 real(real64),
allocatable :: hpsi(:, :), rho1(:), rho(:), dpsi(:, :), dpsi2(:, :)
1284 real(real64),
allocatable :: v_ij(:,:,:,:,:)
1288 integer :: ist, jst, nspin_, iorb, jorb
1293 nspin_ = min(st%d%nspin, 2)
1295 if (.not. rdm%do_basis)
then
1296 safe_allocate(hpsi(1:gr%np, 1:st%d%dim))
1297 safe_allocate(rho1(1:gr%np))
1298 safe_allocate(rho(1:gr%np))
1299 safe_allocate(dpsi(1:gr%np_part, 1:st%d%dim))
1300 safe_allocate(dpsi2(1:gr%np, 1:st%d%dim))
1301 safe_allocate(v_ij(1:gr%np, 1:st%nst, 1:st%nst, 1:st%nik, 1:st%nik))
1315 rdm%eone(ist) =
dmf_dotp(gr, dpsi(:, 1), hpsi(:, 1))
1329 rho1(1:gr%np) = dpsi(1:gr%np, 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)
1335 rho(1:gr%np) = dpsi2(1:gr%np, 1)*dpsi(1:gr%np, 1)
1336 rdm%exchange(ist, jst) =
dmf_dotp(gr, rho, v_ij(:, ist, jst, 1, 1))
1337 rdm%exchange(jst, ist) = rdm%exchange(ist, jst)
1342 safe_deallocate_a(hpsi)
1343 safe_deallocate_a(rho)
1344 safe_deallocate_a(rho1)
1345 safe_deallocate_a(dpsi)
1346 safe_deallocate_a(dpsi2)
1347 safe_deallocate_a(v_ij)
1355 dd = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1356 rdm%eone(iorb) = rdm%eone(iorb) + dd*rdm%eone_int(ist, jst)
1363 rdm%hartree(iorb ,jorb) =
m_zero
1364 rdm%exchange(iorb,jorb) =
m_zero
1367 dd = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1368 rdm%hartree(iorb ,jorb) = rdm%hartree(iorb ,jorb)+rdm%Coul(ist,jst, jorb)*dd
1369 rdm%exchange(iorb ,jorb) = rdm%exchange(iorb ,jorb)+rdm%Exch(ist,jst, jorb)*dd
1372 rdm%hartree(jorb, iorb) = rdm%hartree(iorb, jorb)
1373 rdm%exchange(jorb, iorb) = rdm%exchange(iorb, jorb)
1384 type(
rdm_t),
intent(inout) :: rdm
1388 class(
mesh_t),
intent(in) :: mesh
1390 real(real64),
allocatable :: hpsi(:, :)
1391 real(real64),
allocatable :: dpsi(:, :), dpsi2(:, :)
1396 safe_allocate(dpsi(1:mesh%np_part, 1:st%d%dim))
1397 safe_allocate(dpsi2(1:mesh%np, 1:st%d%dim))
1398 safe_allocate(hpsi(1:mesh%np, 1:st%d%dim))
1403 do jst = ist, st%nst
1409 rdm%eone_int(jst, ist) =
dmf_dotp(mesh, dpsi2(:, 1), hpsi(:, 1))
1410 rdm%eone_int(ist, jst) = rdm%eone_int(jst, ist)
1414 safe_deallocate_a(hpsi)
1415 safe_deallocate_a(dpsi)
1416 safe_deallocate_a(dpsi2)
1424 type(
rdm_t),
intent(inout) :: rdm
1426 integer :: ist, jst, kst, lst, iorb, icount
1427 logical :: inv_pairs
1428 real(real64) :: two_int, wij, wik, wil, wjk, wjl, wkl
1429 real(real64),
allocatable :: dm(:,:,:)
1433 safe_allocate(dm(1:rdm%nst, 1:rdm%nst, 1:rdm%nst))
1439 do iorb = 1, rdm%nst
1442 dm(ist, jst, iorb) = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1443 dm(jst, ist, iorb) = dm(ist, jst, iorb)
1448 do icount = 1, rdm%n_twoint
1450 ist = rdm%i_index(1,icount)
1451 jst = rdm%j_index(1,icount)
1452 kst = rdm%k_index(1,icount)
1453 lst = rdm%l_index(1,icount)
1455 two_int = rdm%twoint(icount)
1469 if(ist == kst .and. jst /= lst)
then
1474 if(ist == lst .and. jst /= kst)
then
1479 if(jst == kst .and. ist /= lst)
then
1484 if(jst == lst .and. ist /= kst)
then
1490 inv_pairs = (ist /= kst .or. jst /= lst)
1492 do iorb = 1, rdm%nst
1495 rdm%Coul(ist, jst, iorb) = rdm%Coul(ist, jst, iorb) + dm(kst, lst, iorb)*wkl*two_int
1496 if (inv_pairs) rdm%Coul(kst, lst, iorb) = rdm%Coul(kst, lst, iorb) + dm(ist, jst, iorb)*wij*two_int
1500 rdm%Exch(ist, kst, iorb) = rdm%Exch(ist, kst, iorb) + two_int*dm(jst, lst, iorb)*wik
1501 if (kst /= lst)
then
1502 rdm%Exch(ist, lst, iorb) = rdm%Exch(ist, lst, iorb) + two_int*dm(jst, kst, iorb)*wil
1504 if (ist /= jst)
then
1506 rdm%Exch(jst, kst, iorb) = rdm%Exch(jst, kst, iorb) + two_int*dm(ist, lst, iorb)*wjk
1508 if (inv_pairs) rdm%Exch(kst, jst, iorb) = rdm%Exch(kst, jst, iorb) + two_int*dm(ist, lst, iorb)
1511 if (ist /=jst .and. kst /= lst)
then
1512 if (jst >= lst)
then
1513 rdm%Exch(jst, lst, iorb) = rdm%Exch(jst, lst, iorb) + two_int*dm(ist, kst, iorb)*wjl
1515 if (inv_pairs) rdm%Exch(lst, jst, iorb) = rdm%Exch(lst, jst, iorb) + two_int*dm(ist, kst, iorb)
1525 rdm%Coul(jst, ist, iorb) = rdm%Coul(ist, jst, iorb)
1526 rdm%Exch(jst, ist, iorb) = rdm%Exch(ist, jst, iorb)
1531 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 contains some common usage patterns of MPI routines.
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.