18 integer,
parameter ::
dp = kind(1.0d0)
44 occErrLimit, traceLimit, x_bml, mu, beta, h1, hN, sgnlist)
48 type(bml_matrix_t),
intent(in) :: h_bml
49 type(bml_matrix_t),
intent(inout) :: x_bml
50 integer,
intent(in) :: nsteps
51 integer,
intent(inout) :: sgnlist(:)
52 real(
dp),
intent(in) :: nocc, tscale, threshold
53 real(
dp),
intent(in) :: occerrlimit, tracelimit
54 real(
dp),
intent(inout) :: mu, beta, h1, hn
56 type(bml_matrix_t) :: x1_bml, x2_bml, tmp_bml, i_bml
57 real(
dp) :: lambda, occerr, sfactor
58 real(
dp) :: tracex0, tracex1, tracex2, tracex
59 real(
dp),
allocatable :: gbnd(:), trace(:)
61 character(20) :: bml_type
64 bml_type = bml_get_type(h_bml)
71 call bml_gershgorin(h_bml, gbnd)
72 mu = 0.5 * (gbnd(2) + gbnd(1))
84 call bml_identity_matrix(bml_type, bml_element_real,
dp, n, m, i_bml)
85 call bml_zero_matrix(bml_type, bml_element_real,
dp, n, m, x1_bml)
86 call bml_zero_matrix(bml_type, bml_element_real,
dp, n, m, x2_bml)
87 call bml_zero_matrix(bml_type, bml_element_real,
dp, n, m, tmp_bml)
89 do while (occerr .gt. occerrlimit)
91 call bml_copy(h_bml, x_bml)
95 call bml_copy(i_bml, x1_bml)
96 sfactor = -1.0_dp / (hn - h1)
97 call bml_scale(sfactor, x1_bml)
100 call bml_multiply_x2(x_bml, x2_bml, threshold, trace)
105 if (firsttime .eqv. .true.)
then
106 if (abs(tracex2-nocc) .lt. abs(2.0_dp*tracex0-tracex2-nocc))
then
118 call bml_multiply(x_bml, x1_bml, tmp_bml, 1.0_dp, 0.0_dp, threshold)
119 call bml_multiply(x1_bml, x_bml, tmp_bml, 1.0_dp, 1.0_dp, threshold)
121 if (sgnlist(i) .eq. 1)
then
123 call bml_add_deprecated(2.0_dp, x1_bml, -1.0_dp, tmp_bml, threshold)
125 call bml_copy(tmp_bml, x1_bml)
132 if (sgnlist(i) .eq. 1)
then
134 call bml_add_deprecated(2.0_dp, x_bml, -1.0_dp, x2_bml, threshold)
136 call bml_copy(x2_bml, x_bml)
142 tracex0 = bml_trace(x_bml)
143 tracex1 = bml_trace(x1_bml)
144 occerr = abs(nocc - tracex0)
146 if (abs(tracex1) .gt. tracelimit)
then
147 lambda = (nocc - tracex0) / tracex1
155 call bml_deallocate(x2_bml)
159 call bml_add_deprecated(1.0_dp, i_bml, -1.0_dp, x_bml, threshold)
161 call bml_multiply(x_bml, i_bml, tmp_bml, 1.0_dp, 0.0_dp, threshold)
162 tracex = bml_trace(tmp_bml)
163 tracex1 = bml_trace(x1_bml)
164 if (abs(tracex) .gt. tracelimit)
then
165 beta = -tracex1 / tracex
173 call bml_deallocate(tmp_bml)
174 call bml_deallocate(i_bml)
175 call bml_deallocate(x1_bml)
199 occErrLimit, traceLimit, x_bml, mu, beta, h1, hN, sgnlist, verbose)
203 type(bml_matrix_t),
intent(in) :: h_bml
204 type(bml_matrix_t),
intent(inout) :: x_bml
205 integer,
intent(inout) :: nsteps
206 integer,
intent(inout) :: sgnlist(:)
207 real(
dp),
intent(in) :: nocc, tscale, threshold
208 real(
dp),
intent(in) :: occerrlimit, tracelimit
209 real(
dp),
intent(inout) :: mu, beta, h1, hn
211 type(bml_matrix_t) :: x1_bml, x2_bml, tmp_bml, i_bml
212 real(
dp) :: lambda, occerr, sfactor, maxder
213 real(
dp) :: tracex0, tracex1, tracex2, tracex, beta0
214 real(
dp),
allocatable :: gbnd(:), trace(:), probe(:), probe_2(:)
216 character(20) :: bml_type
218 integer,
optional :: verbose
220 if(
present(verbose))
then
221 if(verbose >= 1)
write(*,*)
"Inside prg_sp2_fermi_init_norecs ..."
224 bml_type = bml_get_type(h_bml)
232 call bml_gershgorin(h_bml, gbnd)
233 mu = 0.5 * (gbnd(2) + gbnd(1))
234 h1 = tscale * gbnd(1)
235 hn = tscale * gbnd(2)
243 call bml_identity_matrix(bml_type, bml_element_real,
dp, n, m, i_bml)
244 call bml_zero_matrix(bml_type, bml_element_real,
dp, n, m, x1_bml)
245 call bml_zero_matrix(bml_type, bml_element_real,
dp, n, m, x2_bml)
246 call bml_zero_matrix(bml_type, bml_element_real,
dp, n, m, tmp_bml)
248 allocate(probe(1000),probe_2(1000))
250 do while (occerr .gt. occerrlimit)
252 call bml_copy(h_bml, x_bml)
257 probe(i) = 1.0_dp - i*0.001_dp
261 call bml_copy(i_bml, x1_bml)
262 sfactor = -1.0_dp / (hn - h1)
263 call bml_scale(sfactor, x1_bml)
266 call bml_multiply_x2(x_bml, x2_bml, threshold, trace)
268 probe_2(:) = probe(:)*probe(:)
274 if (firsttime .eqv. .true.)
then
275 if (abs(tracex2-nocc) .lt. abs(2.0_dp*tracex0-tracex2-nocc))
then
287 call bml_multiply(x_bml, x1_bml, tmp_bml, 1.0_dp, 0.0_dp, threshold)
288 call bml_multiply(x1_bml, x_bml, tmp_bml, 1.0_dp, 1.0_dp, threshold)
290 if (sgnlist(i) .eq. 1)
then
292 call bml_add_deprecated(2.0_dp, x1_bml, -1.0_dp, tmp_bml, threshold)
294 call bml_copy(tmp_bml, x1_bml)
301 if (sgnlist(i) .eq. 1)
then
303 call bml_add_deprecated(2.0_dp, x_bml, -1.0_dp, x2_bml, threshold)
304 probe = 2.0_dp*probe - probe_2
306 call bml_copy(x2_bml, x_bml)
311 beta = (4.0_dp*maxder)/(gbnd(2)-gbnd(1))
312 if(beta > beta0)
then
324 if(
present(verbose))
then
325 if(verbose >= 1)
then
326 write(*,*)
"beta = ",beta
327 write(*,*)
"kbT = ",1.0_dp/beta
332 tracex0 = bml_trace(x_bml)
333 tracex1 = bml_trace(x1_bml)
334 occerr = abs(nocc - tracex0)
336 if (abs(tracex1) .gt. tracelimit)
then
337 lambda = (nocc - tracex0) / tracex1
345 call bml_deallocate(x2_bml)
349 call bml_add_deprecated(1.0_dp, i_bml, -1.0_dp, x_bml, threshold)
351 call bml_print_matrix(
"x_bml",x_bml,1,4,1,4)
352 call bml_print_matrix(
"i_bml",i_bml,1,4,1,4)
353 call bml_multiply(x_bml, i_bml, tmp_bml, 1.0_dp, 0.0_dp, threshold)
355 call bml_print_matrix(
"tmp_bml",tmp_bml,1,4,1,4)
357 tracex = bml_trace(tmp_bml)
358 tracex1 = bml_trace(x1_bml)
359 if (abs(tracex) .gt. tracelimit)
then
360 beta = -tracex1 / tracex
368 call bml_deallocate(tmp_bml)
369 call bml_deallocate(i_bml)
370 call bml_deallocate(x1_bml)
388 subroutine prg_sp2_fermi(h_bml, osteps, nsteps, nocc, mu, beta, h1, hN, sgnlist, &
389 threshold, eps, traceLimit, x_bml)
393 type(bml_matrix_t),
intent(in) :: h_bml
394 type(bml_matrix_t),
intent(inout) :: x_bml
395 integer,
intent(in) :: osteps, nsteps
396 integer,
intent(in) :: sgnlist(:)
397 real(
dp),
intent(in) :: nocc, threshold, eps, tracelimit
398 real(
dp),
intent(inout) :: beta, h1, hn
399 real(
dp),
intent(inout) :: mu
401 type(bml_matrix_t) :: x2_bml, dx_bml, i_bml
402 real(
dp),
allocatable :: trace(:), gbnd(:)
403 real(
dp) :: sfactor, occerr, tracex0, tracex2, tracedx, lambda
405 integer :: iter, i, n, m
406 character(20) :: bml_type
408 bml_type = bml_get_type(h_bml)
414 call bml_identity_matrix(bml_type, bml_element_real,
dp, n, m, i_bml)
415 call bml_zero_matrix(bml_type, bml_element_real,
dp, n, m, dx_bml)
416 call bml_zero_matrix(bml_type, bml_element_real,
dp, n, m, x2_bml)
418 occerr = 1.0_dp + eps
420 do while ((osteps .eq. 0 .and. occerr .gt. eps) .or. &
421 (osteps .gt. 0 .and. iter .lt. osteps))
423 call bml_copy(h_bml, x_bml)
427 call bml_multiply_x2(x_bml, x2_bml, threshold, trace)
432 if (sgnlist(i) .eq. 1)
then
433 call bml_add_deprecated(2.0_dp, x_bml, -1.0_dp, x2_bml, threshold)
435 call bml_copy(x2_bml, x_bml)
440 tracex0 = bml_trace(x_bml)
441 occerr = abs(nocc - tracex0)
444 call bml_copy(i_bml, x2_bml)
445 call bml_add_deprecated(1.0_dp, x2_bml, -1.0_dp, x_bml, threshold)
446 call bml_multiply(x_bml, x2_bml, dx_bml, -beta, 0.0_dp, threshold)
447 tracedx = bml_trace(dx_bml)
450 if (abs(tracedx) .gt. tracelimit)
then
451 lambda = (nocc - tracex0) / tracedx
460 call bml_add_deprecated(1.0_dp, x_bml, lambda, dx_bml, threshold)
466 call bml_deallocate(i_bml)
467 call bml_deallocate(x2_bml)
468 call bml_deallocate(dx_bml)
486 real(
dp),
intent(in) :: mu, h1, hn
487 integer,
intent(in) :: nsteps, sgnlist(:)
488 real(
dp),
intent(inout),
allocatable :: gg(:), ee(:)
490 real(
dp) :: dh, c1, c2, x1, x2, iint
491 real(
dp) :: a, b, c_1, c_2, x_1, x_2
497 x1 = 0.5773502691896257_dp
501 if (
allocated(gg))
then
504 if (
allocated(ee))
then
521 c_1 = c1*(b-a)/2.0_dp
522 c_2 = c2*(b-a)/2.0_dp;
523 x_1 = ((b-a)*x1+(b+a))/2.0_dp
524 x_2 = ((b-a)*x2+(b+a))/2.0_dp
525 iint = iint + c_1*
sp2_inverse(x_1,mu,h1,hn,nsteps,sgnlist)
526 iint = iint + c_2*
sp2_inverse(x_2,mu,h1,hn,nsteps,sgnlist)
544 type(bml_matrix_t),
intent(in) :: d0_bml
545 real(
dp),
intent(in) :: gg(*), ee(*)
548 type(bml_matrix_t) :: aux_bml
549 real(
dp),
allocatable :: hh(:)
550 real(
dp) :: hs, threshold
552 character(20) :: bml_type, bml_dmode
554 n = bml_get_n(d0_bml)
555 bml_type = bml_get_type(d0_bml)
556 bml_dmode = bml_get_distribution_mode(d0_bml)
561 call bml_zero_matrix(bml_type, bml_element_real, &
564 call bml_diagonalize(d0_bml, hh, aux_bml)
566 call bml_deallocate(aux_bml)
572 j = floor(hs/0.0001_dp + 0.00000_dp) + 1
574 if (j .gt. 0 .and. j .le. 10001)
then
575 ts = ts + ((hs-ee(j))*gg(j+1) + &
576 (ee(j+1)-hs)*gg(j))/(ee(j+1)-ee(j))
596 real(
dp),
intent(in) :: f, mu, h1, hn
597 integer,
intent(in) :: nsteps, sgnlist(:)
599 real(
dp) :: sgn, c, ee
604 sgn = float(sgnlist(i))
605 c = (1.0_dp+sgn)/2.0_dp
606 ee = c - sgn*sqrt(abs(c - sgn*ee))
609 ee = hn-mu-ee*(hn-h1)
620 real(
dp),
intent(in) :: func(:), de
625 do j=1,
size(func, dim=1)-1
The prg_normalize module.
subroutine, public prg_normalize_fermi(h_bml, h1, hN, mu)
Normalize a Hamiltonian matrix prior to running the truncated SP2 algorithm.
real(dp) function, public sp2_entropy_ts(D0_bml, GG, ee)
Test SP2 entropy. Get the entropy contribution TS to the total free energy.
subroutine, public prg_sp2_fermi(h_bml, osteps, nsteps, nocc, mu, beta, h1, hN, sgnlist, threshold, eps, traceLimit, x_bml)
Calculate Truncated SP2.
real(dp) function absmaxderivative(func, de)
Gets the absolute maximum of the derivative of a function.
real(dp) function, public sp2_inverse(f, mu, h1, hN, nsteps, sgnlist)
Calculate the SP2 inverse.
subroutine, public prg_sp2_fermi_init_norecs(h_bml, nsteps, nocc, tscale, threshold, occErrLimit, traceLimit, x_bml, mu, beta, h1, hN, sgnlist, verbose)
Truncated SP2 prg_initialization. This routine also gives back the Number of SP2 recursive steps that...
subroutine, public prg_sp2_fermi_init(h_bml, nsteps, nocc, tscale, threshold, occErrLimit, traceLimit, x_bml, mu, beta, h1, hN, sgnlist)
Truncated SP2 prg_initialization.
subroutine, public prg_sp2_entropy_function(mu, h1, hN, nsteps, sgnlist, GG, ee)
Calculate SP2 entropy function using gaussian quadrature. Note that GG and ee are allocated and retur...