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(:,:)
112 type(elec_matrix_elements_t) :: elec_me
115 type(rdm_t),
pointer :: rdm_ptr
120 subroutine rdmft_init(rdm, namespace, gr, st, mc, space, fromScratch)
121 type(rdm_t),
intent(out) :: rdm
122 type(namespace_t),
intent(in) :: namespace
123 type(grid_t),
intent(inout) :: gr
124 type(states_elec_t),
intent(in) :: st
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.)
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))
230 if (rdm%eigens%additional_terms)
call messages_not_implemented(
"CG Additional Terms with RDMFT", namespace=namespace)
233 safe_allocate(rdm%eone(1:rdm%nst))
234 safe_allocate(rdm%hartree(1:rdm%nst, 1:rdm%nst))
235 safe_allocate(rdm%exchange(1:rdm%nst, 1:rdm%nst))
236 safe_allocate(rdm%evalues(1:rdm%nst))
245 rdm%scale_f = 1e-2_real64
250 call rdm%elec_me%init(gr, space, st)
258 type(
rdm_t),
intent(inout) :: rdm
262 safe_deallocate_a(rdm%evalues)
263 safe_deallocate_a(rdm%eone)
264 safe_deallocate_a(rdm%hartree)
265 safe_deallocate_a(rdm%exchange)
267 if (rdm%do_basis)
then
268 safe_deallocate_a(rdm%eone_int)
269 safe_deallocate_a(rdm%twoint)
270 safe_deallocate_a(rdm%i_index)
271 safe_deallocate_a(rdm%j_index)
272 safe_deallocate_a(rdm%k_index)
273 safe_deallocate_a(rdm%l_index)
274 safe_deallocate_a(rdm%vecnat)
275 safe_deallocate_a(rdm%Coul)
276 safe_deallocate_a(rdm%Exch)
287 subroutine scf_rdmft(rdm, namespace, space, gr, ions, ext_partners, st, ks, hm, outp, restart_dump)
288 type(
rdm_t),
intent(inout) :: rdm
291 type(
grid_t),
intent(in) :: gr
292 type(
ions_t),
intent(in) :: ions
295 type(
v_ks_t),
intent(inout) :: ks
298 type(
restart_t),
intent(in) :: restart_dump
301 integer :: iter, icount, ip, ist, ierr, maxcount, iorb
302 integer(int64) :: what_i
303 real(real64) :: energy, energy_dif, energy_old, energy_occ, xpos, xneg, rel_ener
304 real(real64),
allocatable :: dpsi(:,:), dpsi2(:,:)
306 character(len=MAX_PATH_LEN) :: dirname
310 if (hm%d%ispin /= 1)
then
316 if (space%is_periodic())
then
321 if(st%parallel_in_states)
then
329 energy_old = 1.0e20_real64
333 if (.not. rdm%do_basis)
then
338 write(
message(1),
'(a)')
'Calculating Coulomb and exchange matrix elements in basis'
339 write(
message(2),
'(a)')
'--this may take a while--'
342 call rdm%elec_me%two_body_me(namespace, hm%kpoints, hm%exxop%psolver, 1, st%nst, rdm%i_index, rdm%j_index, rdm%k_index, &
343 rdm%l_index, rdm%twoint)
351 do iter = 1, rdm%max_iter
352 rdm%iter = rdm%iter + 1
353 write(
message(1),
'(a)')
'**********************************************************************'
354 write(
message(2),
'(a, i4)')
'Iteration:', iter
358 call scf_occ_no(rdm, namespace, gr, hm, space, st, energy_occ)
360 call scf_occ(rdm, namespace, gr, hm, space, st, energy_occ)
363 write(
message(1),
'(a)')
'Optimization of natural orbitals'
365 do icount = 1, maxcount
366 if (rdm%do_basis)
then
367 call scf_orb(rdm, namespace, gr, st, hm, space, energy)
369 call scf_orb_cg(rdm, namespace, space, gr, ions, ext_partners, st, ks, hm, energy)
371 energy_dif = energy - energy_old
373 if (rdm%do_basis)
then
374 if (abs(energy_dif)/abs(energy) < rdm%conv_ener .and. rdm%maxFO < rdm%tolerFO)
exit
375 if (energy_dif <
m_zero)
then
380 if (xneg > 1.5e0_real64*xpos)
then
381 rdm%scale_f = 1.01_real64*rdm%scale_f
382 elseif (xneg < 1.1e0_real64*xpos)
then
383 rdm%scale_f = 0.95_real64* rdm%scale_f
390 rel_ener = abs(energy_occ-energy)/abs(energy)
393 write(
message(2),
'(a,1x,es20.10)')
'Rel. energy difference:', rel_ener
396 if (.not. rdm%hf .and. rdm%do_basis)
then
397 write(
message(1),
'(a,18x,es20.10)')
'Max F0:', rdm%maxFO
402 if (rdm%do_basis)
then
403 conv = (rel_ener < rdm%conv_ener) .and. rdm%maxFO < rdm%tolerFO
405 conv = rel_ener < rdm%conv_ener
408 if (rdm%toler > 1e-4_real64) rdm%toler = rdm%toler*1e-1_real64
411 if ((conv .or. (modulo(iter, outp%restart_write_interval) == 0) .or. iter == rdm%max_iter))
then
412 if (rdm%do_basis)
then
414 safe_allocate(dpsi(1:gr%np, 1:st%d%dim))
415 safe_allocate(dpsi2(1:gr%np, 1:st%d%dim))
421 dpsi(ip,1) = dpsi(ip,1) + rdm%vecnat(ist, iorb)*dpsi2(ip,1)
428 call states_elec_dump(restart_dump, space, states_save, gr, hm%kpoints, ierr, iter=iter)
430 if (conv .or. iter == rdm%max_iter)
then
437 safe_deallocate_a(dpsi)
438 safe_deallocate_a(dpsi2)
440 call states_elec_dump(restart_dump, space, st, gr, hm%kpoints, ierr, iter=iter)
443 if (.not. rdm%hf)
then
445 write(
message(1),
'(a,18x,es20.10)')
'Max F0:', rdm%maxFO
451 message(1) =
'Unable to write states wavefunctions.'
458 if (any(outp%what) .and. outp%duringscf)
then
459 do what_i = lbound(outp%what, 1), ubound(outp%what, 1)
460 if (outp%what_now(what_i, iter))
then
461 write(dirname,
'(a,a,i4.4)') trim(outp%iter_dir),
"scf.", iter
462 call output_all(outp, namespace, space, dirname, gr, ions, iter, st, hm, ks)
463 call output_modelmb(outp, namespace, space, dirname, gr, ions, iter, st)
474 write(
message(1),
'(a,i3,a)')
'The calculation converged after ',rdm%iter,
' iterations'
478 write(
message(1),
'(a,i3,a)')
'The calculation did not converge after ', iter-1,
' iterations '
479 write(
message(2),
'(a,es15.5)')
'Relative energy difference between the last two iterations ', rel_ener
480 write(
message(3),
'(a,es15.5)')
'The maximal non-diagonal element of the Hermitian matrix F is ', rdm%maxFO
493 character(len=*),
intent(in) :: dir, fname
495 integer :: iunit, ist
496 real(real64),
allocatable :: photon_number_state (:), ekin_state (:), epot_state (:)
500 safe_allocate(photon_number_state(1:st%nst))
501 safe_allocate(ekin_state(1:st%nst))
502 safe_allocate(epot_state(1:st%nst))
506 iunit =
io_open(trim(dir) //
"/" // trim(fname), namespace, action=
'write')
512 if (rdm%do_basis)
then
513 write(iunit,
'(a)')
'Orbital optimization with [basis set]'
515 write(iunit,
'(a)')
'Orbital optimization with [conjugated gradients]'
520 write(iunit,
'(a)')
'Hartree Fock calculation'
524 if (hm%psolver%is_dressed)
then
525 write(iunit,
'(a)')
'Dressed state calculation'
532 write(iunit,
'(a, i4, a)')
'SCF converged in ', iter,
' iterations'
534 write(iunit,
'(a)')
'SCF *not* converged!'
540 write(iunit,
'(a,1x,f16.12)')
'Sum of occupation numbers:', rdm%occsum
545 if (hm%psolver%is_dressed)
then
546 call calc_photon_number(space, gr, st, hm%psolver%photons, photon_number_state, ekin_state, epot_state)
548 write(iunit,
'(a,1x,f14.12)')
'Total mode occupation:', hm%psolver%photons%number(1)
553 if (rdm%max_iter > 0)
then
554 write(iunit,
'(a)')
'Convergence:'
555 write(iunit,
'(6x, a, es15.8,a,es15.8,a)')
'maxFO = ', rdm%maxFO
556 write(iunit,
'(6x, a, es15.8,a,es15.8,a)')
'rel_ener = ', rel_ener
564 write(iunit,
'(a)')
'Natural occupation numbers:'
565 write(iunit,
'(a4,5x,a12)', advance=
'no')
'#st',
'Occupation'
566 if (.not. rdm%do_basis)
write(iunit,
'(5x,a12)', advance=
'no')
'conv'
567 if (hm%psolver%is_dressed)
write(iunit,
'(3(5x,a12))', advance=
'no')
'Mode Occ.',
'-1/2d^2/dq^2',
'1/2w^2q^2'
572 write(iunit,
'(i4,3x,f14.12)', advance=
'no') ist, st%occ(ist, 1)
573 if (.not. rdm%do_basis)
write(iunit,
'(3x,f14.12)', advance=
'no') rdm%eigens%diff(ist, 1)
574 if (hm%psolver%is_dressed)
then
575 write(iunit,
'(3(3x,f14.12))', advance=
'no') photon_number_state(ist), ekin_state(ist), epot_state(ist)
585 safe_deallocate_a(photon_number_state)
586 safe_deallocate_a(ekin_state)
587 safe_deallocate_a(epot_state)
594 subroutine calc_maxfo (namespace, hm, st, gr, rdm)
596 type(
rdm_t),
intent(inout) :: rdm
597 type(
grid_t),
intent(in) :: gr
601 real(real64),
allocatable :: lambda(:,:), FO(:,:)
606 safe_allocate(lambda(1:st%nst,1:st%nst))
607 safe_allocate(fo(1:st%nst, 1:st%nst))
617 fo(jst, ist) = - (lambda(jst, ist) - lambda(ist ,jst))
620 rdm%maxFO = maxval(abs(fo))
622 safe_deallocate_a(lambda)
623 safe_deallocate_a(fo)
629 subroutine calc_photon_number(space, gr, st, photons, photon_number_state, ekin_state, epot_state)
630 class(
space_t),
intent(in) :: space
631 type(
grid_t),
intent(in) :: gr
634 real(real64),
intent(out) :: photon_number_state(:)
635 real(real64),
intent(out) :: ekin_state(:)
636 real(real64),
intent(out) :: epot_state(:)
638 integer :: ist, dim_photon
639 real(real64) :: q2_exp, laplace_exp
640 real(real64),
allocatable :: psi(:, :), psi_q2(:), dpsidq(:), d2psidq2(:)
645 dim_photon = space%dim
647 safe_allocate(psi(1:gr%np_part, 1))
648 safe_allocate(psi_q2(1:gr%np))
649 safe_allocate(dpsidq(1:gr%np_part))
650 safe_allocate(d2psidq2(1:gr%np))
652 photons%number(1) =
m_zero
660 laplace_exp =
dmf_dotp(gr, psi(:, 1), d2psidq2(:))
661 ekin_state(ist) = -
m_half*laplace_exp
664 psi_q2(1:gr%np) = psi(1:gr%np, 1) * gr%x(1:gr%np, dim_photon)**2
665 q2_exp =
dmf_dotp(gr, psi(:, 1), psi_q2(:))
666 epot_state(ist) =
m_half * photons%omega(1)**2 * q2_exp
670 photon_number_state(ist) = -
m_half*laplace_exp / photons%omega(1) +
m_half * photons%omega(1) * q2_exp
671 photon_number_state(ist) = photon_number_state(ist) -
m_half
674 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
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
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
814 sumgi1 = rdm%occsum - st%qtot
819 sumgi2 = rdm%occsum - st%qtot
822 do while (sumgi1*sumgi2 >
m_zero)
831 sumgi1 = rdm%occsum - st%qtot
840 sumgi2 = rdm%occsum - st%qtot
850 sumgim = rdm%occsum - st%qtot
852 if (sumgi1*sumgim <
m_zero)
then
862 if (st%occ(ist,1) <= thresh_occ ) st%occ(ist,1) = thresh_occ
865 if (abs(sumgim) < rdm%toler .or. abs((mu1-mu2)*
m_half) < rdm%toler)
exit
870 if (icycle >= 50)
then
871 write(
message(1),
'(a,1x,f11.4)')
'Bisection ended without finding mu, sum of occupation numbers:', rdm%occsum
876 st%occ(ist, 1) = st%smear%el_per_state*
sin(theta(ist)*
m_pi*
m_two)**2
879 objective = objective + rdm%mu*(rdm%occsum - rdm%qtot)
882 write(
message(1),
'(a4,5x,a12)')
'#st',
'Occupation'
886 write(
message(1),
'(i4,3x,f14.12)') ist, st%occ(ist, 1)
890 write(
message(1),
'(a,3x,f11.9)')
'Sum of occupation numbers: ', rdm%occsum
894 safe_deallocate_a(occin)
895 safe_deallocate_a(theta)
903 integer,
intent(in) :: size
904 real(real64),
intent(in) :: theta(size)
905 real(real64),
intent(inout) :: objective
906 integer,
intent(in) :: getgrad
907 real(real64),
intent(inout) :: df(size)
910 real(real64) :: thresh_occ, thresh_theta
911 real(real64),
allocatable :: dE_dn(:),occ(:)
915 assert(
size == rdm_ptr%nst)
917 safe_allocate(de_dn(1:size))
918 safe_allocate(occ(1:size))
924 thresh_occ = 1e-14_real64
929 if (occ(ist) <= thresh_occ ) occ(ist) = thresh_occ
932 rdm_ptr%occsum = sum(occ(1:size))
939 if (occ(ist) <= thresh_occ )
then
945 objective = objective - rdm_ptr%mu*(rdm_ptr%occsum - rdm_ptr%qtot)
947 safe_deallocate_a(de_dn)
948 safe_deallocate_a(occ)
955 integer,
intent(in) :: iter
956 integer,
intent(in) :: size
957 real(real64),
intent(in) :: energy, maxdr, maxdf
958 real(real64),
intent(in) :: theta(size)
968 subroutine scf_orb(rdm, namespace, gr, st, hm, space, energy)
969 type(
rdm_t),
intent(inout) :: rdm
971 type(
grid_t),
intent(in) :: gr
974 class(
space_t),
intent(in) :: space
975 real(real64),
intent(out) :: energy
978 real(real64),
allocatable :: lambda(:,:), fo(:,:)
984 safe_allocate(lambda(1:st%nst,1:st%nst))
985 safe_allocate(fo(1:st%nst, 1:st%nst))
993 if (rdm%iter==1)
then
996 fo(ist, jst) =
m_half*(lambda(ist, jst) + lambda(jst, ist))
997 fo(jst, ist) = fo(ist, jst)
1003 fo(jst, ist) = - ( lambda(jst, ist) - lambda(ist ,jst))
1006 rdm%maxfo = maxval(abs(fo))
1008 fo(ist, ist) = rdm%evalues(ist)
1010 if(abs(fo(jst, ist)) > rdm%scale_f)
then
1011 fo(jst, ist) = rdm%scale_f*fo(jst,ist)/abs(fo(jst, ist))
1013 fo(ist, jst) = fo(jst, ist)
1024 safe_deallocate_a(lambda)
1025 safe_deallocate_a(fo)
1035 subroutine scf_orb_cg(rdm, namespace, space, gr, ions, ext_partners, st, ks, hm, energy)
1036 type(
rdm_t),
intent(inout) :: rdm
1039 type(
grid_t),
intent(in) :: gr
1040 type(
ions_t),
intent(in) :: ions
1043 type(
v_ks_t),
intent(inout) :: ks
1045 real(real64),
intent(out) :: energy
1047 integer :: ik, ist, maxiter
1053 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners)
1054 call hm%update(gr, namespace, space, ext_partners)
1056 rdm%eigens%converged = 0
1060 do ik = st%d%kpt%start, st%d%kpt%end
1061 rdm%eigens%matvec = 0
1062 maxiter = rdm%eigens%es_maxiter
1063 call deigensolver_cg(namespace, gr, st, hm, hm%xc, rdm%eigens%pre, rdm%eigens%tolerance, maxiter, &
1064 rdm%eigens%converged(ik), ik, rdm%eigens%diff(:, ik), rdm%eigens%energy_change_threshold, &
1065 rdm%eigens%orthogonalize_to_all, rdm%eigens%conjugate_direction, rdm%eigens%additional_terms)
1067 if (.not. rdm%eigens%folded_spectrum)
then
1069 rdm%eigens%converged(ik) = 0
1071 if(rdm%eigens%diff(ist, ik) < rdm%eigens%tolerance)
then
1072 rdm%eigens%converged(ik) = ist
1081 write(stdout,
'(1x)')
1086 call v_ks_calc(ks, namespace, space, hm, st, ions, ext_partners)
1087 call hm%update(gr, namespace, space, ext_partners)
1103 type(
grid_t),
intent(in) :: gr
1104 real(real64),
intent(out) :: lambda(:,:)
1105 type(
rdm_t),
intent(inout) :: rdm
1107 real(real64),
allocatable :: hpsi(:,:), hpsi1(:,:), dpsi(:,:), dpsi1(:,:)
1108 real(real64),
allocatable :: fock(:,:,:), fvec(:)
1109 integer :: ist, iorb, jorb, jst
1116 if (.not. rdm%do_basis)
then
1117 safe_allocate(hpsi(1:gr%np,1:st%d%dim))
1118 safe_allocate(hpsi1(1:gr%np,1:st%d%dim))
1119 safe_allocate(dpsi(1:gr%np_part ,1:st%d%dim))
1120 safe_allocate(dpsi1(1:gr%np_part ,1:st%d%dim))
1126 do jorb = iorb, st%nst
1129 lambda(jorb, iorb) =
dmf_dotp(gr, dpsi1(:,1), hpsi(:,1))
1132 if (.not. iorb == jorb )
then
1134 lambda(iorb, jorb) =
dmf_dotp(gr, dpsi(:,1), hpsi1(:,1))
1142 safe_allocate(fvec(1:st%nst))
1143 safe_allocate(fock(1:st%nst, 1:st%nst, 1:st%nst))
1149 fock(ist, jst, iorb) = st%occ(iorb, 1)*rdm%eone_int(ist,jst)
1152 fock(ist ,jst, iorb) = fock(ist, jst, iorb) + st%occ(iorb, 1)*st%occ(jorb, 1)*rdm%Coul(ist, jst, jorb) &
1153 -
sqrt(st%occ(iorb, 1))*
sqrt(st%occ(jorb, 1))*rdm%Exch(ist, jst, jorb)
1155 fock(jst, ist, iorb) = fock(ist, jst, iorb)
1164 fvec(ist) = fvec(ist) + fock(ist, jst, jorb)*rdm%vecnat(jst, jorb)
1168 lambda(iorb, jorb) =
m_zero
1170 lambda(iorb, jorb) = lambda(iorb, jorb) + rdm%vecnat(ist, iorb)*fvec(ist)
1177 if (.not. rdm%do_basis)
then
1178 safe_deallocate_a(hpsi)
1179 safe_deallocate_a(hpsi1)
1180 safe_deallocate_a(dpsi)
1181 safe_deallocate_a(dpsi1)
1183 safe_deallocate_a(fvec)
1184 safe_deallocate_a(fock)
1194 type(
rdm_t),
intent(inout) :: rdm
1196 real(real64),
intent(in) :: lambda(:, :)
1198 integer :: iorb, jorb, ist
1199 real(real64),
allocatable :: vecnat_new(:,:)
1201 push_sub(assign_eigenfunctions)
1203 safe_allocate(vecnat_new(1:st%nst, 1:st%nst))
1206 vecnat_new(ist, iorb) =
m_zero
1208 vecnat_new(ist , iorb) = vecnat_new(ist, iorb) + rdm%vecnat(ist, jorb)*lambda(jorb, iorb)
1213 rdm%vecnat = vecnat_new
1215 safe_deallocate_a(vecnat_new)
1217 pop_sub(assign_eigenfunctions)
1224 type(
rdm_t),
intent(in) :: rdm
1225 real(real64),
intent(in) :: occ(:)
1226 real(real64),
intent(out) :: energy
1227 real(real64),
optional,
intent(out) :: dE_dn(:)
1230 real(real64),
allocatable :: V_h(:), V_x(:)
1234 safe_allocate(v_h(1:rdm%nst))
1235 safe_allocate(v_x(1:rdm%nst))
1245 v_h(ist) = v_h(ist) + occ(jst)*rdm%hartree(ist, jst)
1246 v_x(ist) = v_x(ist) -
sqrt(occ(jst))*rdm%exchange(ist, jst)
1248 v_x(ist) = v_x(ist)*
m_half/max(
sqrt(occ(ist)), 1.0e-16_real64)
1253 if (
present(de_dn))
then
1254 de_dn(:) = rdm%eone(:) + v_h(:) + v_x(:)
1259 energy = energy + occ(ist)*rdm%eone(ist) &
1260 +
m_half*occ(ist)*v_h(ist) &
1264 safe_deallocate_a(v_h)
1265 safe_deallocate_a(v_x)
1273 type(
rdm_t),
intent(inout) :: rdm
1277 type(
grid_t),
intent(in) :: gr
1278 class(
space_t),
intent(in) :: space
1281 real(real64),
allocatable :: hpsi(:,:), rho1(:), rho(:), dpsi(:,:), dpsi2(:,:)
1282 real(real64),
allocatable :: v_ij(:,:,:,:,:)
1286 integer :: ist, jst, nspin_, iorb, jorb
1291 nspin_ = min(st%d%nspin, 2)
1293 if (rdm%do_basis.eqv..false.)
then
1294 safe_allocate(hpsi(1:gr%np, 1:st%d%dim))
1295 safe_allocate(rho1(1:gr%np))
1296 safe_allocate(rho(1:gr%np))
1297 safe_allocate(dpsi(1:gr%np_part, 1:st%d%dim))
1298 safe_allocate(dpsi2(1:gr%np, 1:st%d%dim))
1299 safe_allocate(v_ij(1:gr%np, 1:st%nst, 1:st%nst, 1:st%nik, 1:st%nik))
1313 rdm%eone(ist) =
dmf_dotp(gr, dpsi(:, 1), hpsi(:, 1))
1327 rho1(1:gr%np) = dpsi(1:gr%np, 1)**2
1329 do jst = ist, st%nst
1330 rdm%hartree(ist, jst) =
dmf_dotp(gr, rho1, v_ij(:,jst, jst, 1, 1))
1331 rdm%hartree(jst, ist) = rdm%hartree(ist, jst)
1333 rho(1:gr%np) = dpsi2(1:gr%np, 1)*dpsi(1:gr%np, 1)
1334 rdm%exchange(ist, jst) =
dmf_dotp(gr, rho, v_ij(:, ist, jst, 1, 1))
1335 rdm%exchange(jst, ist) = rdm%exchange(ist, jst)
1340 safe_deallocate_a(hpsi)
1341 safe_deallocate_a(rho)
1342 safe_deallocate_a(rho1)
1343 safe_deallocate_a(dpsi)
1344 safe_deallocate_a(dpsi2)
1345 safe_deallocate_a(v_ij)
1353 dd = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1354 rdm%eone(iorb) = rdm%eone(iorb) + dd*rdm%eone_int(ist, jst)
1361 rdm%hartree(iorb ,jorb) =
m_zero
1362 rdm%exchange(iorb,jorb) =
m_zero
1365 dd = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1366 rdm%hartree(iorb ,jorb) = rdm%hartree(iorb ,jorb)+rdm%Coul(ist,jst, jorb)*dd
1367 rdm%exchange(iorb ,jorb) = rdm%exchange(iorb ,jorb)+rdm%Exch(ist,jst, jorb)*dd
1370 rdm%hartree(jorb, iorb) = rdm%hartree(iorb, jorb)
1371 rdm%exchange(jorb, iorb) = rdm%exchange(iorb, jorb)
1382 type(
rdm_t),
intent(inout) :: rdm
1386 class(
mesh_t),
intent(in) :: mesh
1388 real(real64),
allocatable :: hpsi(:,:)
1389 real(real64),
allocatable :: dpsi(:,:), dpsi2(:,:)
1394 safe_allocate(dpsi(1:mesh%np_part, 1:st%d%dim))
1395 safe_allocate(dpsi2(1:mesh%np, 1:st%d%dim))
1396 safe_allocate(hpsi(1:mesh%np, 1:st%d%dim))
1401 do jst = ist, st%nst
1407 rdm%eone_int(jst, ist) =
dmf_dotp(mesh, dpsi2(:, 1), hpsi(:, 1))
1408 rdm%eone_int(ist, jst) = rdm%eone_int(jst, ist)
1412 safe_deallocate_a(hpsi)
1413 safe_deallocate_a(dpsi)
1414 safe_deallocate_a(dpsi2)
1422 type(
rdm_t),
intent(inout) :: rdm
1424 integer :: ist, jst, kst, lst, iorb, icount
1425 logical :: inv_pairs
1426 real(real64) :: two_int, wij, wik, wil, wjk, wjl, wkl
1427 real(real64),
allocatable :: dm(:,:,:)
1431 safe_allocate(dm(1:rdm%nst, 1:rdm%nst, 1:rdm%nst))
1437 do iorb = 1, rdm%nst
1440 dm(ist, jst, iorb) = rdm%vecnat(ist, iorb)*rdm%vecnat(jst, iorb)
1441 dm(jst, ist, iorb) = dm(ist, jst, iorb)
1446 do icount = 1, rdm%n_twoint
1448 ist = rdm%i_index(1,icount)
1449 jst = rdm%j_index(1,icount)
1450 kst = rdm%k_index(1,icount)
1451 lst = rdm%l_index(1,icount)
1453 two_int = rdm%twoint(icount)
1467 if(ist == kst .and. jst /= lst)
then
1472 if(ist == lst .and. jst /= kst)
then
1477 if(jst == kst .and. ist /= lst)
then
1482 if(jst == lst .and. ist /= kst)
then
1488 inv_pairs = (ist /= kst .or. jst /= lst)
1490 do iorb = 1, rdm%nst
1493 rdm%Coul(ist, jst, iorb) = rdm%Coul(ist, jst, iorb) + dm(kst, lst, iorb)*wkl*two_int
1494 if (inv_pairs) rdm%Coul(kst, lst, iorb) = rdm%Coul(kst, lst, iorb) + dm(ist, jst, iorb)*wij*two_int
1498 rdm%Exch(ist, kst, iorb) = rdm%Exch(ist, kst, iorb) + two_int*dm(jst, lst, iorb)*wik
1499 if (kst /= lst)
then
1500 rdm%Exch(ist, lst, iorb) = rdm%Exch(ist, lst, iorb) + two_int*dm(jst, kst, iorb)*wil
1502 if (ist /= jst)
then
1504 rdm%Exch(jst, kst, iorb) = rdm%Exch(jst, kst, iorb) + two_int*dm(ist, lst, iorb)*wjk
1506 if (inv_pairs) rdm%Exch(kst, jst, iorb) = rdm%Exch(kst, jst, iorb) + two_int*dm(ist, lst, iorb)
1509 if (ist /=jst .and. kst /= lst)
then
1510 if (jst >= lst)
then
1511 rdm%Exch(jst, lst, iorb) = rdm%Exch(jst, lst, iorb) + two_int*dm(ist, kst, iorb)*wjl
1513 if (inv_pairs) rdm%Exch(lst, jst, iorb) = rdm%Exch(lst, jst, iorb) + two_int*dm(ist, kst, iorb)
1523 rdm%Coul(jst, ist, iorb) = rdm%Coul(ist, jst, iorb)
1524 rdm%Exch(jst, ist, iorb) = rdm%Exch(ist, jst, iorb)
1529 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 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.