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, 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(multicomm_t),
intent(in) :: mc
124 class(space_t),
intent(in) :: space
125 logical,
intent(in) :: fromScratch
129 if(st%nst < st%qtot + 1)
then
130 message(1) =
"Too few states to run RDMFT calculation"
131 message(2) =
"Number of states should be at least the number of electrons plus one"
152 call parse_variable(namespace,
'RDMTolerance', 1.0e-7_real64, rdm%toler)
163 call parse_variable(namespace,
'RDMToleranceFO', 1.0e-4_real64, rdm%tolerFO)
188 if (rdm%do_basis .and. fromscratch)
then
189 call messages_write(
"RDMFT calculations with RDMBasis = yes cannot be started FromScratch", new_line=.
true.)
205 if (rdm%do_basis)
then
206 rdm%n_twoint = rdm%nst*(rdm%nst + 1)*(rdm%nst**2 + rdm%nst + 2)/8
207 safe_allocate(rdm%eone_int(1:rdm%nst, 1:rdm%nst))
208 safe_allocate(rdm%twoint(1:rdm%n_twoint))
209 safe_allocate(rdm%i_index(1:2,1:rdm%n_twoint))
210 safe_allocate(rdm%j_index(1:2,1:rdm%n_twoint))
211 safe_allocate(rdm%k_index(1:2,1:rdm%n_twoint))
212 safe_allocate(rdm%l_index(1:2,1:rdm%n_twoint))
213 safe_allocate(rdm%vecnat(1:rdm%nst, 1:rdm%nst))
214 safe_allocate(rdm%Coul(1:rdm%nst, 1:rdm%nst, 1:rdm%nst))
215 safe_allocate(rdm%Exch(1:rdm%nst, 1:rdm%nst, 1:rdm%nst))
228 if (rdm%eigens%additional_terms)
call messages_not_implemented(
"CG Additional Terms with RDMFT", namespace=namespace)
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))
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, gr, ions, ext_partners, st, ks, hm, outp, restart_dump)
283 type(
rdm_t),
intent(inout) :: rdm
286 type(
grid_t),
intent(in) :: gr
287 type(
ions_t),
intent(in) :: ions
290 type(
v_ks_t),
intent(inout) :: ks
293 type(
restart_t),
intent(in) :: restart_dump
296 integer :: iter, icount, ip, ist, ierr, maxcount, iorb
297 integer(int64) :: what_i
298 real(real64) :: energy, energy_dif, energy_old, energy_occ, xpos, xneg, rel_ener
299 real(real64),
allocatable :: dpsi(:,:), dpsi2(:,:)
301 character(len=MAX_PATH_LEN) :: dirname
305 if (hm%d%ispin /= 1)
then
311 if (space%is_periodic())
then
316 if(st%parallel_in_states)
then
324 energy_old = 1.0e20_real64
328 if (.not. rdm%do_basis)
then
333 write(
message(1),
'(a)')
'Calculating Coulomb and exchange matrix elements in basis'
334 write(
message(2),
'(a)')
'--this may take a while--'
337 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, &
338 rdm%l_index, rdm%twoint)
346 do iter = 1, rdm%max_iter
347 rdm%iter = rdm%iter + 1
348 write(
message(1),
'(a)')
'**********************************************************************'
349 write(
message(2),
'(a, i4)')
'Iteration:', iter
353 call scf_occ_no(rdm, namespace, gr, hm, space, st, energy_occ)
355 call scf_occ(rdm, namespace, gr, hm, space, st, energy_occ)
358 write(
message(1),
'(a)')
'Optimization of natural orbitals'
360 do icount = 1, maxcount
361 if (rdm%do_basis)
then
362 call scf_orb(rdm, namespace, gr, st, hm, space, energy)
364 call scf_orb_cg(rdm, namespace, space, gr, ions, ext_partners, st, ks, hm, energy)
366 energy_dif = energy - energy_old
368 if (rdm%do_basis)
then
369 if (abs(energy_dif)/abs(energy) < rdm%conv_ener .and. rdm%maxFO < rdm%tolerFO)
exit
370 if (energy_dif <
m_zero)
then
375 if (xneg > 1.5e0_real64*xpos)
then
376 rdm%scale_f = 1.01_real64*rdm%scale_f
377 elseif (xneg < 1.1e0_real64*xpos)
then
378 rdm%scale_f = 0.95_real64* rdm%scale_f
385 rel_ener = abs(energy_occ-energy)/abs(energy)
388 write(
message(2),
'(a,1x,es20.10)')
'Rel. energy difference:', rel_ener
391 if (.not. rdm%hf .and. rdm%do_basis)
then
392 write(
message(1),
'(a,18x,es20.10)')
'Max F0:', rdm%maxFO
397 if (rdm%do_basis)
then
398 conv = (rel_ener < rdm%conv_ener) .and. rdm%maxFO < rdm%tolerFO
400 conv = rel_ener < rdm%conv_ener
403 if (rdm%toler > 1e-4_real64) rdm%toler = rdm%toler*1e-1_real64
406 if ((conv .or. (modulo(iter, outp%restart_write_interval) == 0) .or. iter == rdm%max_iter))
then
407 if (rdm%do_basis)
then
409 safe_allocate(dpsi(1:gr%np, 1:st%d%dim))
410 safe_allocate(dpsi2(1:gr%np, 1:st%d%dim))
416 dpsi(ip,1) = dpsi(ip,1) + rdm%vecnat(ist, iorb)*dpsi2(ip,1)
423 call states_elec_dump(restart_dump, space, states_save, gr, hm%kpoints, ierr, iter=iter)
425 if (conv .or. iter == rdm%max_iter)
then
432 safe_deallocate_a(dpsi)
433 safe_deallocate_a(dpsi2)
435 call states_elec_dump(restart_dump, space, st, gr, hm%kpoints, ierr, iter=iter)
438 if (.not. rdm%hf)
then
440 write(
message(1),
'(a,18x,es20.10)')
'Max F0:', rdm%maxFO
446 message(1) =
'Unable to write states wavefunctions.'
453 if (any(outp%what) .and. outp%duringscf)
then
454 do what_i = lbound(outp%what, 1), ubound(outp%what, 1)
455 if (outp%what_now(what_i, iter))
then
456 write(dirname,
'(a,a,i4.4)') trim(outp%iter_dir),
"scf.", iter
457 call output_all(outp, namespace, space, dirname, gr, ions, iter, st, hm, ks)
458 call output_modelmb(outp, namespace, space, dirname, gr, ions, iter, st)
469 write(
message(1),
'(a,i3,a)')
'The calculation converged after ',rdm%iter,
' iterations'
473 write(
message(1),
'(a,i3,a)')
'The calculation did not converge after ', iter-1,
' iterations '
474 write(
message(2),
'(a,es15.5)')
'Relative energy difference between the last two iterations ', rel_ener
475 write(
message(3),
'(a,es15.5)')
'The maximal non-diagonal element of the Hermitian matrix F is ', rdm%maxFO
488 character(len=*),
intent(in) :: dir, fname
490 integer :: iunit, ist
491 real(real64),
allocatable :: photon_number_state (:), ekin_state (:), epot_state (:)
495 safe_allocate(photon_number_state(1:st%nst))
496 safe_allocate(ekin_state(1:st%nst))
497 safe_allocate(epot_state(1:st%nst))
501 iunit =
io_open(trim(dir) //
"/" // trim(fname), namespace, action=
'write')
507 if (rdm%do_basis)
then
508 write(iunit,
'(a)')
'Orbital optimization with [basis set]'
510 write(iunit,
'(a)')
'Orbital optimization with [conjugated gradients]'
515 write(iunit,
'(a)')
'Hartree Fock calculation'
519 if (hm%psolver%is_dressed)
then
520 write(iunit,
'(a)')
'Dressed state calculation'
527 write(iunit,
'(a, i4, a)')
'SCF converged in ', iter,
' iterations'
529 write(iunit,
'(a)')
'SCF *not* converged!'
535 write(iunit,
'(a,1x,f16.12)')
'Sum of occupation numbers:', rdm%occsum
540 if (hm%psolver%is_dressed)
then
541 call calc_photon_number(space, gr, st, hm%psolver%photons, photon_number_state, ekin_state, epot_state)
543 write(iunit,
'(a,1x,f14.12)')
'Total mode occupation:', hm%psolver%photons%number(1)
548 if (rdm%max_iter > 0)
then
549 write(iunit,
'(a)')
'Convergence:'
550 write(iunit,
'(6x, a, es15.8,a,es15.8,a)')
'maxFO = ', rdm%maxFO
551 write(iunit,
'(6x, a, es15.8,a,es15.8,a)')
'rel_ener = ', rel_ener
559 write(iunit,
'(a)')
'Natural occupation numbers:'
560 write(iunit,
'(a4,5x,a12)', advance=
'no')
'#st',
'Occupation'
561 if (.not. rdm%do_basis)
write(iunit,
'(5x,a12)', advance=
'no')
'conv'
562 if (hm%psolver%is_dressed)
write(iunit,
'(3(5x,a12))', advance=
'no')
'Mode Occ.',
'-1/2d^2/dq^2',
'1/2w^2q^2'
567 write(iunit,
'(i4,3x,f14.12)', advance=
'no') ist, st%occ(ist, 1)
568 if (.not. rdm%do_basis)
write(iunit,
'(3x,f14.12)', advance=
'no') rdm%eigens%diff(ist, 1)
569 if (hm%psolver%is_dressed)
then
570 write(iunit,
'(3(3x,f14.12))', advance=
'no') photon_number_state(ist), ekin_state(ist), epot_state(ist)
580 safe_deallocate_a(photon_number_state)
581 safe_deallocate_a(ekin_state)
582 safe_deallocate_a(epot_state)
589 subroutine calc_maxfo (namespace, hm, st, gr, rdm)
591 type(
rdm_t),
intent(inout) :: rdm
592 type(
grid_t),
intent(in) :: gr
596 real(real64),
allocatable :: lambda(:,:), FO(:,:)
601 safe_allocate(lambda(1:st%nst,1:st%nst))
602 safe_allocate(fo(1:st%nst, 1:st%nst))
612 fo(jst, ist) = - (lambda(jst, ist) - lambda(ist ,jst))
615 rdm%maxFO = maxval(abs(fo))
617 safe_deallocate_a(lambda)
618 safe_deallocate_a(fo)
624 subroutine calc_photon_number(space, gr, st, photons, photon_number_state, ekin_state, epot_state)
625 class(
space_t),
intent(in) :: space
626 type(
grid_t),
intent(in) :: gr
629 real(real64),
intent(out) :: photon_number_state(:)
630 real(real64),
intent(out) :: ekin_state(:)
631 real(real64),
intent(out) :: epot_state(:)
633 integer :: ist, dim_photon
634 real(real64) :: q2_exp, laplace_exp
635 real(real64),
allocatable :: psi(:, :), psi_q2(:), dpsidq(:), d2psidq2(:)
640 dim_photon = space%dim
642 safe_allocate(psi(1:gr%np_part, 1))
643 safe_allocate(psi_q2(1:gr%np))
644 safe_allocate(dpsidq(1:gr%np_part))
645 safe_allocate(d2psidq2(1:gr%np))
647 photons%number(1) =
m_zero
655 laplace_exp =
dmf_dotp(gr, psi(:, 1), d2psidq2(:))
656 ekin_state(ist) = -
m_half*laplace_exp
659 psi_q2(1:gr%np) = psi(1:gr%np, 1) * gr%x(1:gr%np, dim_photon)**2
660 q2_exp =
dmf_dotp(gr, psi(:, 1), psi_q2(:))
661 epot_state(ist) =
m_half * photons%omega(1)**2 * q2_exp
665 photon_number_state(ist) = -
m_half*laplace_exp / photons%omega(1) +
m_half * photons%omega(1) * q2_exp
666 photon_number_state(ist) = photon_number_state(ist) -
m_half
669 photons%number(1) = photons%number(1) + (photon_number_state(ist) +
m_half)*st%occ(ist, 1)
672 photons%number(1) = photons%number(1) - st%qtot/
m_two
674 safe_deallocate_a(psi)
675 safe_deallocate_a(psi_q2)
676 safe_deallocate_a(dpsidq)
677 safe_deallocate_a(d2psidq2)
688 real(real64),
allocatable :: occin(:,:)
692 safe_allocate(occin(1:st%nst, 1:st%nik))
694 occin(1:st%nst, 1:st%nik) = st%occ(1:st%nst, 1:st%nik)
696 where(occin(:,:) >
m_one) occin(:,:) = st%smear%el_per_state
700 safe_deallocate_a(occin)
709 subroutine scf_occ_no(rdm, namespace, gr, hm, space, st, energy)
710 type(
rdm_t),
intent(inout) :: rdm
712 type(
grid_t),
intent(in) :: gr
714 class(
space_t),
intent(in) :: space
716 real(real64),
intent(out) :: energy
722 write(
message(1),
'(a)')
'SKIP Optimization of occupation numbers'
733 rdm%occsum = sum(st%occ(1:st%nst, 1:st%nik))
735 write(
message(1),
'(a4,5x,a12)')
'#st',
'Occupation'
739 write(
message(1),
'(i4,3x,f11.9)') ist, st%occ(ist, 1)
743 write(
message(1),
'(a,1x,f13.9)')
'Sum of occupation numbers', rdm%occsum
751 subroutine scf_occ(rdm, namespace, gr, hm, space, st, energy)
752 type(
rdm_t),
target,
intent(inout) :: rdm
754 type(
grid_t),
intent(in) :: gr
756 class(
space_t),
intent(in) :: space
758 real(real64),
intent(out) :: energy
760 integer :: ist, icycle, ierr
761 real(real64) :: sumgi1, sumgi2, sumgim, mu1, mu2, mum, dinterv, thresh_occ
762 real(real64),
allocatable :: occin(:,:)
763 real(real64),
parameter :: smallocc = 0.00001_real64
764 real(real64),
allocatable :: theta(:)
765 real(real64) :: objective
770 write(
message(1),
'(a)')
'Optimization of occupation numbers'
773 safe_allocate(occin(1:st%nst, 1:st%nik))
774 safe_allocate(theta(1:st%nst))
782 thresh_occ = 1e-14_real64
785 occin(1:st%nst, 1:st%nik) = st%occ(1:st%nst, 1:st%nik)
786 where(occin(:,:) < smallocc) occin(:,:) = smallocc
787 where(occin(:,:) > st%smear%el_per_state - smallocc) occin(:,:) = st%smear%el_per_state - smallocc
809 sumgi1 = rdm%occsum - st%qtot
814 sumgi2 = rdm%occsum - st%qtot
817 do while (sumgi1*sumgi2 >
m_zero)
826 sumgi1 = rdm%occsum - st%qtot
835 sumgi2 = rdm%occsum - st%qtot
845 sumgim = rdm%occsum - st%qtot
847 if (sumgi1*sumgim <
m_zero)
then
857 if (st%occ(ist,1) <= thresh_occ ) st%occ(ist,1) = thresh_occ
860 if (abs(sumgim) < rdm%toler .or. abs((mu1-mu2)*
m_half) < rdm%toler)
exit
865 if (icycle >= 50)
then
866 write(
message(1),
'(a,1x,f11.4)')
'Bisection ended without finding mu, sum of occupation numbers:', rdm%occsum
871 st%occ(ist, 1) = st%smear%el_per_state*
sin(theta(ist)*
m_pi*
m_two)**2
874 objective = objective + rdm%mu*(rdm%occsum - rdm%qtot)
877 write(
message(1),
'(a4,5x,a12)')
'#st',
'Occupation'
881 write(
message(1),
'(i4,3x,f14.12)') ist, st%occ(ist, 1)
885 write(
message(1),
'(a,3x,f11.9)')
'Sum of occupation numbers: ', rdm%occsum
889 safe_deallocate_a(occin)
890 safe_deallocate_a(theta)
898 integer,
intent(in) :: size
899 real(real64),
intent(in) :: theta(size)
900 real(real64),
intent(inout) :: objective
901 integer,
intent(in) :: getgrad
902 real(real64),
intent(inout) :: df(size)
905 real(real64) :: thresh_occ, thresh_theta
906 real(real64),
allocatable :: dE_dn(:),occ(:)
910 assert(
size == rdm_ptr%nst)
912 safe_allocate(de_dn(1:size))
913 safe_allocate(occ(1:size))
919 thresh_occ = 1e-14_real64
924 if (occ(ist) <= thresh_occ ) occ(ist) = thresh_occ
927 rdm_ptr%occsum = sum(occ(1:size))
934 if (occ(ist) <= thresh_occ )
then
940 objective = objective - rdm_ptr%mu*(rdm_ptr%occsum - rdm_ptr%qtot)
942 safe_deallocate_a(de_dn)
943 safe_deallocate_a(occ)
950 integer,
intent(in) :: iter
951 integer,
intent(in) :: size
952 real(real64),
intent(in) :: energy, maxdr, maxdf
953 real(real64),
intent(in) :: theta(size)
963 subroutine scf_orb(rdm, namespace, gr, st, hm, space, energy)
964 type(
rdm_t),
intent(inout) :: rdm
966 type(
grid_t),
intent(in) :: gr
969 class(
space_t),
intent(in) :: space
970 real(real64),
intent(out) :: energy
973 real(real64),
allocatable :: lambda(:,:), fo(:,:)
979 safe_allocate(lambda(1:st%nst,1:st%nst))
980 safe_allocate(fo(1:st%nst, 1:st%nst))
988 if (rdm%iter==1)
then
991 fo(ist, jst) =
m_half*(lambda(ist, jst) + lambda(jst, ist))
992 fo(jst, ist) = fo(ist, jst)
998 fo(jst, ist) = - ( lambda(jst, ist) - lambda(ist ,jst))
1001 rdm%maxfo = maxval(abs(fo))
1003 fo(ist, ist) = rdm%evalues(ist)
1005 if(abs(fo(jst, ist)) > rdm%scale_f)
then
1006 fo(jst, ist) = rdm%scale_f*fo(jst,ist)/abs(fo(jst, ist))
1008 fo(ist, jst) = fo(jst, ist)
1019 safe_deallocate_a(lambda)
1020 safe_deallocate_a(fo)
1030 subroutine scf_orb_cg(rdm, namespace, space, gr, ions, ext_partners, st, ks, hm, energy)
1031 type(
rdm_t),
intent(inout) :: rdm
1034 type(
grid_t),
intent(in) :: gr
1035 type(
ions_t),
intent(in) :: ions
1038 type(
v_ks_t),
intent(inout) :: ks
1040 real(real64),
intent(out) :: energy
1042 integer :: ik, ist, maxiter
1048 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners)
1049 call hm%update(gr, namespace, space, ext_partners)
1051 rdm%eigens%converged = 0
1055 do ik = st%d%kpt%start, st%d%kpt%end
1056 rdm%eigens%matvec = 0
1057 maxiter = rdm%eigens%es_maxiter
1058 call deigensolver_cg(namespace, gr, st, hm, hm%xc, rdm%eigens%pre, rdm%eigens%tolerance, maxiter, &
1059 rdm%eigens%converged(ik), ik, rdm%eigens%diff(:, ik), rdm%eigens%energy_change_threshold, &
1060 rdm%eigens%orthogonalize_to_all, rdm%eigens%conjugate_direction, rdm%eigens%additional_terms)
1062 if (.not. rdm%eigens%folded_spectrum)
then
1064 rdm%eigens%converged(ik) = 0
1066 if(rdm%eigens%diff(ist, ik) < rdm%eigens%tolerance)
then
1067 rdm%eigens%converged(ik) = ist
1076 write(stdout,
'(1x)')
1081 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners)
1082 call hm%update(gr, namespace, space, ext_partners)
1098 type(
grid_t),
intent(in) :: gr
1099 real(real64),
intent(out) :: lambda(:,:)
1100 type(
rdm_t),
intent(inout) :: rdm
1102 real(real64),
allocatable :: hpsi(:,:), hpsi1(:,:), dpsi(:,:), dpsi1(:,:)
1103 real(real64),
allocatable :: fock(:,:,:), fvec(:)
1104 integer :: ist, iorb, jorb, jst
1111 if (.not. rdm%do_basis)
then
1112 safe_allocate(hpsi(1:gr%np,1:st%d%dim))
1113 safe_allocate(hpsi1(1:gr%np,1:st%d%dim))
1114 safe_allocate(dpsi(1:gr%np_part ,1:st%d%dim))
1115 safe_allocate(dpsi1(1:gr%np_part ,1:st%d%dim))
1121 do jorb = iorb, st%nst
1124 lambda(jorb, iorb) =
dmf_dotp(gr, dpsi1(:,1), hpsi(:,1))
1127 if (.not. iorb == jorb )
then
1129 lambda(iorb, jorb) =
dmf_dotp(gr, dpsi(:,1), hpsi1(:,1))
1137 safe_allocate(fvec(1:st%nst))
1138 safe_allocate(fock(1:st%nst, 1:st%nst, 1:st%nst))
1144 fock(ist, jst, iorb) = st%occ(iorb, 1)*rdm%eone_int(ist,jst)
1147 fock(ist ,jst, iorb) = fock(ist, jst, iorb) + st%occ(iorb, 1)*st%occ(jorb, 1)*rdm%Coul(ist, jst, jorb) &
1148 -
sqrt(st%occ(iorb, 1))*
sqrt(st%occ(jorb, 1))*rdm%Exch(ist, jst, jorb)
1150 fock(jst, ist, iorb) = fock(ist, jst, iorb)
1159 fvec(ist) = fvec(ist) + fock(ist, jst, jorb)*rdm%vecnat(jst, jorb)
1163 lambda(iorb, jorb) =
m_zero
1165 lambda(iorb, jorb) = lambda(iorb, jorb) + rdm%vecnat(ist, iorb)*fvec(ist)
1172 if (.not. rdm%do_basis)
then
1173 safe_deallocate_a(hpsi)
1174 safe_deallocate_a(hpsi1)
1175 safe_deallocate_a(dpsi)
1176 safe_deallocate_a(dpsi1)
1178 safe_deallocate_a(fvec)
1179 safe_deallocate_a(fock)
1189 type(
rdm_t),
intent(inout) :: rdm
1191 real(real64),
intent(in) :: lambda(:, :)
1193 integer :: iorb, jorb, ist
1194 real(real64),
allocatable :: vecnat_new(:,:)
1196 push_sub(assign_eigenfunctions)
1198 safe_allocate(vecnat_new(1:st%nst, 1:st%nst))
1201 vecnat_new(ist, iorb) =
m_zero
1203 vecnat_new(ist , iorb) = vecnat_new(ist, iorb) + rdm%vecnat(ist, jorb)*lambda(jorb, iorb)
1208 rdm%vecnat = vecnat_new
1210 safe_deallocate_a(vecnat_new)
1212 pop_sub(assign_eigenfunctions)
1219 type(
rdm_t),
intent(in) :: rdm
1220 real(real64),
intent(in) :: occ(:)
1221 real(real64),
intent(out) :: energy
1222 real(real64),
optional,
intent(out) :: dE_dn(:)
1225 real(real64),
allocatable :: V_h(:), V_x(:)
1229 safe_allocate(v_h(1:rdm%nst))
1230 safe_allocate(v_x(1:rdm%nst))
1240 v_h(ist) = v_h(ist) + occ(jst)*rdm%hartree(ist, jst)
1241 v_x(ist) = v_x(ist) -
sqrt(occ(jst))*rdm%exchange(ist, jst)
1243 v_x(ist) = v_x(ist)*
m_half/max(
sqrt(occ(ist)), 1.0e-16_real64)
1248 if (
present(de_dn))
then
1249 de_dn(:) = rdm%eone(:) + v_h(:) + v_x(:)
1254 energy = energy + occ(ist)*rdm%eone(ist) &
1255 +
m_half*occ(ist)*v_h(ist) &
1259 safe_deallocate_a(v_h)
1260 safe_deallocate_a(v_x)
1268 type(
rdm_t),
intent(inout) :: rdm
1272 type(
grid_t),
intent(in) :: gr
1273 class(
space_t),
intent(in) :: space
1276 real(real64),
allocatable :: hpsi(:,:), rho1(:), rho(:), dpsi(:,:), dpsi2(:,:)
1277 real(real64),
allocatable :: v_ij(:,:,:,:,:)
1281 integer :: ist, jst, nspin_, iorb, jorb
1286 nspin_ = min(st%d%nspin, 2)
1288 if (rdm%do_basis.eqv..false.)
then
1289 safe_allocate(hpsi(1:gr%np, 1:st%d%dim))
1290 safe_allocate(rho1(1:gr%np))
1291 safe_allocate(rho(1:gr%np))
1292 safe_allocate(dpsi(1:gr%np_part, 1:st%d%dim))
1293 safe_allocate(dpsi2(1:gr%np, 1:st%d%dim))
1294 safe_allocate(v_ij(1:gr%np, 1:st%nst, 1:st%nst, 1:st%nik, 1:st%nik))
1308 rdm%eone(ist) =
dmf_dotp(gr, dpsi(:, 1), hpsi(:, 1))
1322 rho1(1:gr%np) = dpsi(1:gr%np, 1)**2
1324 do jst = ist, st%nst
1325 rdm%hartree(ist, jst) =
dmf_dotp(gr, rho1, v_ij(:,jst, jst, 1, 1))
1326 rdm%hartree(jst, ist) = rdm%hartree(ist, jst)
1328 rho(1:gr%np) = dpsi2(1:gr%np, 1)*dpsi(1:gr%np, 1)
1329 rdm%exchange(ist, jst) =
dmf_dotp(gr, rho, v_ij(:, ist, jst, 1, 1))
1330 rdm%exchange(jst, ist) = rdm%exchange(ist, jst)
1335 safe_deallocate_a(hpsi)
1336 safe_deallocate_a(rho)
1337 safe_deallocate_a(rho1)
1338 safe_deallocate_a(dpsi)
1339 safe_deallocate_a(dpsi2)
1340 safe_deallocate_a(v_ij)
1348 dd = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1349 rdm%eone(iorb) = rdm%eone(iorb) + dd*rdm%eone_int(ist, jst)
1356 rdm%hartree(iorb ,jorb) =
m_zero
1357 rdm%exchange(iorb,jorb) =
m_zero
1360 dd = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1361 rdm%hartree(iorb ,jorb) = rdm%hartree(iorb ,jorb)+rdm%Coul(ist,jst, jorb)*dd
1362 rdm%exchange(iorb ,jorb) = rdm%exchange(iorb ,jorb)+rdm%Exch(ist,jst, jorb)*dd
1365 rdm%hartree(jorb, iorb) = rdm%hartree(iorb, jorb)
1366 rdm%exchange(jorb, iorb) = rdm%exchange(iorb, jorb)
1377 type(
rdm_t),
intent(inout) :: rdm
1381 class(
mesh_t),
intent(in) :: mesh
1383 real(real64),
allocatable :: hpsi(:,:)
1384 real(real64),
allocatable :: dpsi(:,:), dpsi2(:,:)
1389 safe_allocate(dpsi(1:mesh%np_part, 1:st%d%dim))
1390 safe_allocate(dpsi2(1:mesh%np, 1:st%d%dim))
1391 safe_allocate(hpsi(1:mesh%np, 1:st%d%dim))
1396 do jst = ist, st%nst
1402 rdm%eone_int(jst, ist) =
dmf_dotp(mesh, dpsi2(:, 1), hpsi(:, 1))
1403 rdm%eone_int(ist, jst) = rdm%eone_int(jst, ist)
1407 safe_deallocate_a(hpsi)
1408 safe_deallocate_a(dpsi)
1409 safe_deallocate_a(dpsi2)
1417 type(
rdm_t),
intent(inout) :: rdm
1419 integer :: ist, jst, kst, lst, iorb, icount
1420 logical :: inv_pairs
1421 real(real64) :: two_int, wij, wik, wil, wjk, wjl, wkl
1422 real(real64),
allocatable :: dm(:,:,:)
1426 safe_allocate(dm(1:rdm%nst, 1:rdm%nst, 1:rdm%nst))
1432 do iorb = 1, rdm%nst
1435 dm(ist, jst, iorb) = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1436 dm(jst, ist, iorb) = dm(ist, jst, iorb)
1441 do icount = 1, rdm%n_twoint
1443 ist = rdm%i_index(1,icount)
1444 jst = rdm%j_index(1,icount)
1445 kst = rdm%k_index(1,icount)
1446 lst = rdm%l_index(1,icount)
1448 two_int = rdm%twoint(icount)
1462 if(ist == kst .and. jst /= lst)
then
1467 if(ist == lst .and. jst /= kst)
then
1472 if(jst == kst .and. ist /= lst)
then
1477 if(jst == lst .and. ist /= kst)
then
1483 inv_pairs = (ist /= kst .or. jst /= lst)
1485 do iorb = 1, rdm%nst
1488 rdm%Coul(ist, jst, iorb) = rdm%Coul(ist, jst, iorb) + dm(kst, lst, iorb)*wkl*two_int
1489 if (inv_pairs) rdm%Coul(kst, lst, iorb) = rdm%Coul(kst, lst, iorb) + dm(ist, jst, iorb)*wij*two_int
1493 rdm%Exch(ist, kst, iorb) = rdm%Exch(ist, kst, iorb) + two_int*dm(jst, lst, iorb)*wik
1494 if (kst /= lst)
then
1495 rdm%Exch(ist, lst, iorb) = rdm%Exch(ist, lst, iorb) + two_int*dm(jst, kst, iorb)*wil
1497 if (ist /= jst)
then
1499 rdm%Exch(jst, kst, iorb) = rdm%Exch(jst, kst, iorb) + two_int*dm(ist, lst, iorb)*wjk
1501 if (inv_pairs) rdm%Exch(kst, jst, iorb) = rdm%Exch(kst, jst, iorb) + two_int*dm(ist, lst, iorb)
1504 if (ist /=jst .and. kst /= lst)
then
1505 if (jst >= lst)
then
1506 rdm%Exch(jst, lst, iorb) = rdm%Exch(jst, lst, iorb) + two_int*dm(ist, kst, iorb)*wjl
1508 if (inv_pairs) rdm%Exch(lst, jst, iorb) = rdm%Exch(lst, jst, iorb) + two_int*dm(ist, kst, iorb)
1518 rdm%Coul(jst, ist, iorb) = rdm%Coul(ist, jst, iorb)
1519 rdm%Exch(jst, ist, iorb) = rdm%Exch(ist, jst, iorb)
1524 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__
subroutine minimize_multidim(method, dim, x, step, line_tol, tolgrad, toldr, maxiter, f, write_iter_info, minimum, ierr)
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, xc, pre, tol, niter, converged, ik, diff, energy_change_threshold, orthogonalize_to_all, conjugate_direction, additional_terms, shift)
conjugate-gradients method.
subroutine, public eigensolver_init(eigens, namespace, gr, st, mc, space)
subroutine, public eigensolver_end(eigens)
subroutine, public dexchange_operator_compute_potentials(this, namespace, space, gr, st, xst, kpoints, ex, 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)
This module contains some common usage patterns of MPI routines.
logical function mpi_grp_is_root(grp)
Is the current MPI process of grpcomm, root.
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 rdmft_init(rdm, namespace, gr, st, 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, public scf_rdmft(rdm, namespace, space, gr, ions, ext_partners, st, ks, hm, outp, restart_dump)
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, st_start_writing, 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)
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.
The states_elec_t class contains all electronic wave functions.