35#include "base/base_uses.f90"
45 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'smearing_utils'
46 INTEGER,
PARAMETER,
PRIVATE :: BISECT_MAX_ITER = 400
74 SUBROUTINE smearocc(f, N, kTS, e, mu, sigma, maxocc, method, estate, festate)
76 REAL(kind=
dp),
INTENT(OUT) :: f(:), n, kts
77 REAL(kind=
dp),
INTENT(IN) :: e(:), mu, sigma, maxocc
78 INTEGER,
INTENT(IN) :: method
79 INTEGER,
INTENT(IN),
OPTIONAL :: estate
80 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: festate
83 REAL(kind=
dp) :: arg, expu2, expx2, occupation, term1, &
84 term2, tmp, tmp2, tmp3, tmp4, tmplog, &
91 IF (
PRESENT(estate) .AND.
PRESENT(festate))
THEN
104 arg = -(e(i) - mu)/sigma
110 term1 = tmp2*(arg + tmplog)
113 arg = (e(i) - mu)/sigma
120 term2 = tmp3*(arg + tmplog)
122 f(i) = occupation*tmp2
123 kts = kts + sigma*occupation*(term1 + term2)
126 x = (e(i) - mu)/sigma
128 f(i) = occupation*0.5_dp*erfc(x)
129 kts = kts - (sigma/(2.0_dp*
rootpi))*occupation*expx2
132 x = (e(i) - mu)/sigma
134 f(i) = occupation*(0.5_dp*erfc(x) - x/(2.0_dp*
rootpi)*expx2)
135 kts = kts + (sigma/(4.0_dp*
rootpi))*occupation*(2.0_dp*x*x - 1.0_dp)*expx2
138 x = (e(i) - mu)/sigma
141 f(i) = occupation*(0.5_dp*erfc(u) + expu2/(
sqrt2*
rootpi))
142 kts = kts - (sigma/(
sqrt2*
rootpi))*occupation*u*expu2
145 cpabort(
"SmearOcc: unknown smearing method")
169 SUBROUTINE smear2(f, nel, kTS, e, mu, wk, sigma, maxocc, method)
171 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: f
172 REAL(kind=
dp),
INTENT(OUT) :: nel, kts
173 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: e
174 REAL(kind=
dp),
INTENT(IN) :: mu
175 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: wk
176 REAL(kind=
dp),
INTENT(IN) :: sigma, maxocc
177 INTEGER,
INTENT(IN) :: method
179 INTEGER :: ik, is, nkp, nmo
180 REAL(kind=
dp) :: arg, expu2, expx2, term1, term2, tmp, &
181 tmp2, tmp3, tmp4, tmplog, u, x
187 IF (sigma > 1.0e-14_dp)
THEN
192 IF (e(is, ik) > mu)
THEN
193 arg = -(e(is, ik) - mu)/sigma
199 term1 = tmp2*(arg + tmplog)
202 arg = (e(is, ik) - mu)/sigma
209 term2 = tmp3*(arg + tmplog)
211 f(is, ik) = maxocc*tmp2
212 kts = kts + sigma*maxocc*(term1 + term2)*wk(ik)
215 x = (e(is, ik) - mu)/sigma
217 f(is, ik) = maxocc*0.5_dp*erfc(x)
218 kts = kts - (sigma/(2.0_dp*
rootpi))*maxocc*expx2*wk(ik)
221 x = (e(is, ik) - mu)/sigma
223 f(is, ik) = maxocc*(0.5_dp*erfc(x) - x/(2.0_dp*
rootpi)*expx2)
224 kts = kts + (sigma/(4.0_dp*
rootpi))*maxocc*(2.0_dp*x*x - 1.0_dp)*expx2*wk(ik)
227 x = (e(is, ik) - mu)/sigma
230 f(is, ik) = maxocc*(0.5_dp*erfc(u) + expu2/(
sqrt2*
rootpi))
231 kts = kts - (sigma/(
sqrt2*
rootpi))*maxocc*u*expu2*wk(ik)
234 cpabort(
"Smear2: unknown smearing method")
242 IF (e(is, ik) <= mu)
THEN
256 END SUBROUTINE smear2
276 SUBROUTINE smearfixed(f, mu, kTS, e, N, sigma, maxocc, method, estate, festate)
278 REAL(kind=
dp),
INTENT(OUT) :: f(:), mu, kts
279 REAL(kind=
dp),
INTENT(IN) :: e(:), n, sigma, maxocc
280 INTEGER,
INTENT(IN) :: method
281 INTEGER,
INTENT(IN),
OPTIONAL :: estate
282 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: festate
284 INTEGER :: iter, my_estate
285 REAL(kind=
dp) :: mu_max, mu_min, mu_now, my_festate, &
288 IF (
PRESENT(estate) .AND.
PRESENT(festate))
THEN
292 my_estate = nint(maxocc)
293 my_festate = my_estate
301 CALL smearocc(f, n_tmp, kts, e, mu_min, sigma, maxocc, method, my_estate, my_festate)
302 IF (n_tmp > n .OR. iter > 20)
THEN
303 mu_min = mu_min - sigma
314 CALL smearocc(f, n_tmp, kts, e, mu_max, sigma, maxocc, method, my_estate, my_festate)
315 IF (n_tmp < n .OR. iter > 20)
THEN
316 mu_max = mu_max + sigma
324 DO WHILE (mu_max - mu_min > epsilon(mu)*max(1.0_dp, abs(mu_max), abs(mu_min)))
326 mu_now = (mu_max + mu_min)/2.0_dp
327 CALL smearocc(f, n_now, kts, e, mu_now, sigma, maxocc, method, my_estate, my_festate)
335 IF (iter > bisect_max_iter)
THEN
336 cpwarn(
"SmearFixed: maximum bisection iterations reached")
341 mu = (mu_max + mu_min)/2.0_dp
342 CALL smearocc(f, n_now, kts, e, mu, sigma, maxocc, method, my_estate, my_festate)
363 SUBROUTINE smearkp(f, mu, kTS, e, nel, wk, sigma, maxocc, method)
365 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: f
366 REAL(kind=
dp),
INTENT(OUT) :: mu, kts
367 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: e
368 REAL(kind=
dp),
INTENT(IN) :: nel
369 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: wk
370 REAL(kind=
dp),
INTENT(IN) :: sigma, maxocc
371 INTEGER,
INTENT(IN) :: method
373 REAL(kind=
dp),
PARAMETER :: epsocc = 1.0e-12_dp
376 REAL(kind=
dp) :: de, mu_max, mu_min, n_now
380 de = sigma*log((1.0_dp - epsocc)/epsocc)
386 mu_min = minval(e) - de
387 mu_max = maxval(e) + de
389 DO WHILE (mu_max - mu_min > epsilon(mu)*max(1.0_dp, abs(mu_max), abs(mu_min)))
391 mu = (mu_max + mu_min)/2.0_dp
392 CALL smear2(f, n_now, kts, e, mu, wk, sigma, maxocc, method)
394 IF (abs(n_now - nel) < nel*epsocc)
EXIT
396 IF (n_now <= nel)
THEN
402 IF (iter > bisect_max_iter)
THEN
403 cpwarn(
"Smearkp: maximum bisection iterations reached")
408 mu = (mu_max + mu_min)/2.0_dp
409 CALL smear2(f, n_now, kts, e, mu, wk, sigma, maxocc, method)
427 SUBROUTINE smearkp2(f, mu, kTS, e, nel, wk, sigma, method)
429 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(OUT) :: f
430 REAL(kind=
dp),
INTENT(OUT) :: mu, kts
431 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN) :: e
432 REAL(kind=
dp),
INTENT(IN) :: nel
433 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: wk
434 REAL(kind=
dp),
INTENT(IN) :: sigma
435 INTEGER,
INTENT(IN) :: method
437 REAL(kind=
dp),
PARAMETER :: epsocc = 1.0e-12_dp
440 REAL(kind=
dp) :: de, ktsa, ktsb, mu_max, mu_min, n_now, &
443 cpassert(
SIZE(f, 3) == 2 .AND.
SIZE(e, 3) == 2)
447 de = sigma*log((1.0_dp - epsocc)/epsocc)
453 mu_min = minval(e) - de
454 mu_max = maxval(e) + de
456 DO WHILE (mu_max - mu_min > epsilon(mu)*max(1.0_dp, abs(mu_max), abs(mu_min)))
458 mu = (mu_max + mu_min)/2.0_dp
459 CALL smear2(f(:, :, 1), na, ktsa, e(:, :, 1), mu, wk, sigma, 1.0_dp, method)
460 CALL smear2(f(:, :, 2), nb, ktsb, e(:, :, 2), mu, wk, sigma, 1.0_dp, method)
463 IF (abs(n_now - nel) < nel*epsocc)
EXIT
465 IF (n_now <= nel)
THEN
471 IF (iter > bisect_max_iter)
THEN
472 cpwarn(
"Smearkp2: maximum bisection iterations reached")
477 mu = (mu_max + mu_min)/2.0_dp
478 CALL smear2(f(:, :, 1), na, ktsa, e(:, :, 1), mu, wk, sigma, 1.0_dp, method)
479 CALL smear2(f(:, :, 2), nb, ktsb, e(:, :, 2), mu, wk, sigma, 1.0_dp, method)
511 SUBROUTINE compute_gvec(gvec, f, e, mu, sigma, maxocc, Nstate, method, estate, festate)
513 REAL(kind=
dp),
INTENT(OUT) :: gvec(:)
514 REAL(kind=
dp),
INTENT(IN) :: f(:), e(:), mu, sigma, maxocc
515 INTEGER,
INTENT(IN) :: nstate, method
516 INTEGER,
INTENT(IN),
OPTIONAL :: estate
517 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: festate
520 REAL(kind=
dp) :: expu2, expx2, fi_norm, occ_i, u, x
523 IF (
PRESENT(estate) .AND.
PRESENT(festate))
THEN
524 IF (i == estate)
THEN
533 IF (occ_i < epsilon(occ_i))
THEN
538 x = (e(i) - mu)/sigma
543 gvec(i) = occ_i*fi_norm*(1.0_dp - fi_norm)/sigma
547 gvec(i) = occ_i/(sigma*
rootpi)*expx2
551 gvec(i) = occ_i*(3.0_dp - 2.0_dp*x*x)/(2.0_dp*sigma*
rootpi)*expx2
556 gvec(i) = occ_i*(2.0_dp +
sqrt2*x)/(sigma*
rootpi)*expu2
561 END SUBROUTINE compute_gvec
592 SUBROUTINE smearfixedderiv(dfde, f, mu, kTS, e, N, sigma, maxocc, method, estate, festate)
594 REAL(kind=
dp),
INTENT(OUT) :: dfde(:, :), f(:), mu, kts
595 REAL(kind=
dp),
INTENT(IN) :: e(:), n, sigma, maxocc
596 INTEGER,
INTENT(IN) :: method
597 INTEGER,
INTENT(IN),
OPTIONAL :: estate
598 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: festate
600 CHARACTER(len=*),
PARAMETER :: routinen =
'SmearFixedDeriv'
602 INTEGER :: handle, i, j, nstate
603 REAL(kind=
dp) :: gsum
604 REAL(kind=
dp),
ALLOCATABLE :: gvec(:)
606 CALL timeset(routinen, handle)
609 CALL smearfixed(f, mu, kts, e, n, sigma, maxocc, method, estate, festate)
613 ALLOCATE (gvec(nstate))
614 CALL compute_gvec(gvec, f, e, mu, sigma, maxocc, nstate, method, estate, festate)
618 IF (abs(gsum) > epsilon(gsum))
THEN
621 dfde(i, j) = gvec(i)*gvec(j)/gsum
623 dfde(j, j) = dfde(j, j) - gvec(j)
630 CALL timestop(handle)
665 SUBROUTINE smearfixedderivmv(RESULT, f, mu, kTS, e, N_el, sigma, maxocc, method, v, estate, festate)
667 REAL(kind=
dp),
INTENT(OUT) :: result(:), f(:), mu, kts
668 REAL(kind=
dp),
INTENT(IN) :: e(:), n_el, sigma, maxocc
669 INTEGER,
INTENT(IN) :: method
670 REAL(kind=
dp),
INTENT(IN) :: v(:)
671 INTEGER,
INTENT(IN),
OPTIONAL :: estate
672 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: festate
674 CHARACTER(len=*),
PARAMETER :: routinen =
'SmearFixedDerivMV'
676 INTEGER :: handle, i, nstate
677 REAL(kind=
dp) :: gdotv, gsum
678 REAL(kind=
dp),
ALLOCATABLE :: gvec(:)
680 CALL timeset(routinen, handle)
683 CALL smearfixed(f, mu, kts, e, n_el, sigma, maxocc, method, estate, festate)
687 ALLOCATE (gvec(nstate))
688 CALL compute_gvec(gvec, f, e, mu, sigma, maxocc, nstate, method, estate, festate)
692 IF (abs(gsum) > epsilon(gsum))
THEN
695 gdotv = gdotv + gvec(i)*v(i)
698 result(i) = gvec(i)*(gdotv/gsum - v(i))
705 CALL timestop(handle)
sums arrays of real/complex numbers with much reduced round-off as compared to a naive implementation...
Defines the basic variable types.
integer, parameter, public dp
Definition of mathematical constants and functions.
real(kind=dp), parameter, public sqrthalf
real(kind=dp), parameter, public rootpi
real(kind=dp), parameter, public sqrt2
Unified smearing module supporting four methods: smear_fermi_dirac — Fermi-Dirac distribution smear_g...
subroutine, public smearkp(f, mu, kts, e, nel, wk, sigma, maxocc, method)
Bisection search for mu given a target electron count (k-point case, single spin channel or spin-dege...
subroutine, public smearkp2(f, mu, kts, e, nel, wk, sigma, method)
Bisection search for mu (k-point, spin-polarised with a shared chemical potential across both spin ch...
subroutine, public smearfixedderiv(dfde, f, mu, kts, e, n, sigma, maxocc, method, estate, festate)
Analytical Jacobian df_i/de_j for any smearing method under the electron-number constraint sum(f) = N...
subroutine, public smearocc(f, n, kts, e, mu, sigma, maxocc, method, estate, festate)
Returns occupations and smearing correction for a given set of energies and chemical potential,...
subroutine, public smearfixed(f, mu, kts, e, n, sigma, maxocc, method, estate, festate)
Bisection search for the chemical potential mu such that the total electron count equals N,...
subroutine, public smearfixedderivmv(result, f, mu, kts, e, n_el, sigma, maxocc, method, v, estate, festate)
Apply TRANSPOSE(df/de) to a vector WITHOUT forming the full N x N Jacobian. O(N) time and O(N) memory...