17 #include "base/base_uses.f90"
25 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'fermi_utils'
26 INTEGER,
PARAMETER,
PRIVATE :: BISECT_MAX_ITER = 400
47 SUBROUTINE fermi(f, N, kTS, e, mu, T, maxocc, estate, festate)
49 REAL(kind=
dp),
INTENT(out) :: f(:), n, kts
50 REAL(kind=
dp),
INTENT(IN) :: e(:), mu, t, maxocc
51 INTEGER,
INTENT(IN),
OPTIONAL :: estate
52 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: festate
55 REAL(kind=
dp) :: arg, occupation, term1, term2, tmp, &
56 tmp2, tmp3, tmp4, tmplog
64 IF (
PRESENT(estate) .AND.
PRESENT(festate))
THEN
83 term1 = tmp2*(arg + tmplog)
94 term2 = tmp3*(arg + tmplog)
97 f(i) = occupation*tmp2
98 kts = kts + t*occupation*(term1 + term2)
116 SUBROUTINE fermi2(f, nel, kTS, e, mu, wk, t, maxocc)
118 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: f
119 REAL(kind=
dp),
INTENT(OUT) :: nel, kts
120 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: e
121 REAL(kind=
dp),
INTENT(IN) :: mu
122 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: wk
123 REAL(kind=
dp),
INTENT(IN) :: t, maxocc
125 INTEGER :: ik, is, nkp, nmo
126 REAL(kind=
dp) :: arg, beta, term1, term2, tmp, tmp2, &
134 IF (t > 1.0e-14_dp)
THEN
138 IF (e(is, ik) > mu)
THEN
139 arg = -(e(is, ik) - mu)*beta
145 term1 = tmp2*(arg + tmplog)
148 arg = (e(is, ik) - mu)*beta
155 term2 = tmp3*(arg + tmplog)
158 f(is, ik) = maxocc*tmp2
159 kts = kts + t*maxocc*(term1 + term2)*wk(ik)
165 IF (e(is, ik) <= mu)
THEN
176 nel = nel + accurate_sum(f(1:nmo, ik))*wk(ik)
179 END SUBROUTINE fermi2
201 SUBROUTINE fermifixed(f, mu, kTS, e, N, T, maxocc, estate, festate)
202 REAL(kind=
dp),
INTENT(OUT) :: f(:), mu, kts
203 REAL(kind=
dp),
INTENT(IN) :: e(:), n, t, maxocc
204 INTEGER,
INTENT(IN),
OPTIONAL :: estate
205 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: festate
207 INTEGER :: iter, my_estate
208 REAL(kind=
dp) :: mu_max, mu_min, mu_now, my_festate, &
211 IF (
PRESENT(estate) .AND.
PRESENT(festate))
THEN
215 my_estate = nint(maxocc)
216 my_festate = my_estate
226 CALL fermi(f, n_min, kts, e, mu_min, t, maxocc, my_estate, my_festate)
227 IF (n_min > n .OR. iter > 20)
THEN
238 CALL fermi(f, n_max, kts, e, mu_max, t, maxocc, my_estate, my_festate)
239 IF (n_max < n .OR. iter > 20)
THEN
248 DO WHILE (mu_max - mu_min > epsilon(mu)*max(1.0_dp, abs(mu_max), abs(mu_min)))
250 mu_now = (mu_max + mu_min)/2.0_dp
251 CALL fermi(f, n_now, kts, e, mu_now, t, maxocc, my_estate, my_festate)
260 IF (iter > bisect_max_iter)
THEN
261 cpwarn(
"Maximum number of iterations reached while finding the Fermi energy")
266 mu = (mu_max + mu_min)/2.0_dp
267 CALL fermi(f, n_now, kts, e, mu, t, maxocc, my_estate, my_festate)
282 SUBROUTINE fermikp(f, mu, kTS, e, nel, wk, t, maxocc)
283 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(OUT) :: f
284 REAL(kind=
dp),
INTENT(OUT) :: mu, kts
285 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: e
286 REAL(kind=
dp),
INTENT(IN) :: nel
287 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: wk
288 REAL(kind=
dp),
INTENT(IN) :: t, maxocc
290 REAL(kind=
dp),
PARAMETER :: epsocc = 1.0e-12_dp
293 REAL(kind=
dp) :: de, mu_max, mu_min, n_now
296 de = t*log((1.0_dp - epsocc)/epsocc)
298 mu_min = minval(e) - de
299 mu_max = maxval(e) + de
301 DO WHILE (mu_max - mu_min > epsilon(mu)*max(1.0_dp, abs(mu_max), abs(mu_min)))
303 mu = (mu_max + mu_min)/2.0_dp
304 CALL fermi2(f, n_now, kts, e, mu, wk, t, maxocc)
306 IF (abs(n_now - nel) < nel*epsocc)
EXIT
308 IF (n_now <= nel)
THEN
314 IF (iter > bisect_max_iter)
THEN
315 cpwarn(
"Maximum number of iterations reached while finding the Fermi energy")
320 mu = (mu_max + mu_min)/2.0_dp
321 CALL fermi2(f, n_now, kts, e, mu, wk, t, maxocc)
336 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(OUT) :: f
337 REAL(kind=
dp),
INTENT(OUT) :: mu, kts
338 REAL(kind=
dp),
DIMENSION(:, :, :),
INTENT(IN) :: e
339 REAL(kind=
dp),
INTENT(IN) :: nel
340 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: wk
341 REAL(kind=
dp),
INTENT(IN) :: t
343 REAL(kind=
dp),
PARAMETER :: epsocc = 1.0e-12_dp
346 REAL(kind=
dp) :: de, ktsa, ktsb, mu_max, mu_min, n_now, &
350 cpassert(
SIZE(f, 3) == 2 .AND.
SIZE(e, 3) == 2)
353 de = t*log((1.0_dp - epsocc)/epsocc)
355 mu_min = minval(e) - de
356 mu_max = maxval(e) + de
358 DO WHILE (mu_max - mu_min > epsilon(mu)*max(1.0_dp, abs(mu_max), abs(mu_min)))
360 mu = (mu_max + mu_min)/2.0_dp
361 CALL fermi2(f(:, :, 1), na, ktsa, e(:, :, 1), mu, wk, t, 1.0_dp)
362 CALL fermi2(f(:, :, 2), nb, ktsb, e(:, :, 2), mu, wk, t, 1.0_dp)
365 IF (abs(n_now - nel) < nel*epsocc)
EXIT
367 IF (n_now <= nel)
THEN
373 IF (iter > bisect_max_iter)
THEN
374 cpwarn(
"Maximum number of iterations reached while finding the Fermi energy")
379 mu = (mu_max + mu_min)/2.0_dp
380 CALL fermi2(f(:, :, 1), na, ktsa, e(:, :, 1), mu, wk, t, 1.0_dp)
381 CALL fermi2(f(:, :, 2), nb, ktsb, e(:, :, 2), mu, wk, t, 1.0_dp)
412 SUBROUTINE fermifixedderiv(dfde, f, mu, kTS, e, N, T, maxocc, l, estate, festate)
413 REAL(kind=
dp),
INTENT(OUT) :: dfde(:, :), f(:), mu, kts
414 REAL(kind=
dp),
INTENT(IN) :: e(:), n, t, maxocc, l
415 INTEGER,
INTENT(IN),
OPTIONAL :: estate
416 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: festate
418 CHARACTER(len=*),
PARAMETER :: routinen =
'FermiFixedDeriv'
420 INTEGER :: handle, i, my_estate, nstate
421 REAL(kind=
dp) :: h, mux, my_festate
422 REAL(kind=
dp),
ALLOCATABLE :: ex(:), fx(:)
424 CALL timeset(routinen, handle)
427 ALLOCATE (ex(nstate), fx(nstate))
429 IF (
PRESENT(estate) .AND.
PRESENT(festate))
THEN
433 my_estate = nint(maxocc)
434 my_festate = my_estate
441 h = (epsilon(h)**(1.0_dp/3.0_dp))*l
443 h = 2.0_dp**exponent(h)
449 CALL fermifixed(fx, mux, kts, ex, n, t, maxocc, my_estate, my_festate)
452 CALL fermifixed(fx, mux, kts, ex, n, t, maxocc, my_estate, my_festate)
453 dfde(:, i) = (dfde(:, i) - fx)/(2.0_dp*h)
457 CALL fermifixed(f, mu, kts, e, n, t, maxocc, my_estate, my_festate)
459 CALL timestop(handle)
deal with the Fermi distribution, compute it, fix mu, get derivs
subroutine, public fermikp2(f, mu, kTS, e, nel, wk, t)
Bisection search to find mu for a given nel (kpoint case)
subroutine, public fermikp(f, mu, kTS, e, nel, wk, t, maxocc)
Bisection search to find mu for a given nel (kpoint case)
subroutine, public fermi(f, N, kTS, e, mu, T, maxocc, estate, festate)
returns occupations according to Fermi-Dirac statistics for a given set of energies and fermi level....
subroutine, public fermifixedderiv(dfde, f, mu, kTS, e, N, T, maxocc, l, estate, festate)
returns f and dfde for a given set of energies and number of electrons it is a numerical derivative,...
subroutine, public fermifixed(f, mu, kTS, e, N, T, maxocc, estate, festate)
returns occupations according to Fermi-Dirac statistics for a given set of energies and number of ele...
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