Octopus
smear.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2006 M. Marques, A. Castro, A. Rubio, G. Bertsch
2!!
3!! This program is free software; you can redistribute it and/or modify
4!! it under the terms of the GNU General Public License as published by
5!! the Free Software Foundation; either version 2, or (at your option)
6!! any later version.
7!!
8!! This program is distributed in the hope that it will be useful,
9!! but WITHOUT ANY WARRANTY; without even the implied warranty of
10!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11!! GNU General Public License for more details.
12!!
13!! You should have received a copy of the GNU General Public License
14!! along with this program; if not, write to the Free Software
15!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
16!! 02110-1301, USA.
17!!
18
19! Some pieces glued from PW/w(0,1)gauss.f90 from PWSCF
20
21#include "global.h"
22
23module smear_oct_m
24 use debug_oct_m
25 use global_oct_m
26 use, intrinsic :: iso_fortran_env
31 use parser_oct_m
34 use sort_oct_m
35 use unit_oct_m
38
39 implicit none
40
41 private
42 public :: &
43 smear_t, &
44 smear_init, &
45 smear_copy, &
54
55 type smear_t
56 private
57 integer, public :: method
58 real(real64), public :: dsmear
59 real(real64) :: dsmear_cond
60 real(real64), public :: e_fermi
61 real(real64) :: e_fermi_cond
62
63 integer, public :: el_per_state
64 real(real64), public :: ef_occ
65 real(real64) :: ef_occ_cond
66 logical, public :: integral_occs
67 integer, public :: MP_n
68 integer :: fermi_count
69 integer :: nik_factor
70 integer :: nspins
71
72 type(simplex_t), pointer :: tetra_simplex => null()
73
74 ! PhotonDoping
75 logical, public:: photodop
76 real(real64) :: nephotodop
77 integer :: photodop_bandmin
78
79 end type smear_t
80
81 integer, parameter, public :: &
82 SMEAR_SEMICONDUCTOR = 1, &
84 smear_cold = 3, &
86 smear_spline = 5, &
87 smear_fixed_occ = 6, &
88 smear_gaussian = option__smearingfunction__gaussian_smearing, &
89 smear_lorentzian = option__smearingfunction__lorentzian_smearing, &
90 smear_tetrahedra = option__smearingfunction__tetrahedra, &
91 smear_tetrahedra_opt = option__smearingfunction__tetrahedra_opt
92
93 real(real64), parameter :: TOL_SMEAR = 1e-6_real64
94
95contains
96
97 !--------------------------------------------------
98 subroutine smear_init(this, namespace, ispin, fixed_occ, integral_occs, kpoints)
99 type(smear_t), intent(out) :: this
100 type(namespace_t), intent(in) :: namespace
101 integer, intent(in) :: ispin
102 logical, intent(in) :: fixed_occ
103 logical, intent(in) :: integral_occs
104 type(kpoints_t), intent(in) :: kpoints
105
106 push_sub(smear_init)
107
108 this%integral_occs = integral_occs
109
110 !%Variable SmearingFunction
111 !%Type integer
112 !%Default semiconducting
113 !%Section States
114 !%Description
115 !% This is the function used to smear the electronic occupations.
116 !% It is ignored if the <tt>Occupations</tt> block is set.
117 !%Option semiconducting 1
118 !% Semiconducting occupations, <i>i.e.</i> the lowest lying states are occupied
119 !% until no more electrons are left.
120 !%Option fermi_dirac 2
121 !% Simple Fermi-Dirac distribution. In this case, <tt>Smearing</tt> has
122 !% the meaning of an electronic temperature. DN Mermin, <i>Phys. Rev.</i> <b>137</b>, A1441 (1965).
123 !%Option cold_smearing 3
124 !% N Marzari, D Vanderbilt, A De Vita, and MC Payne, <i>Phys. Rev. Lett.</i> <b>82</b>, 3296 (1999).
125 !%Option methfessel_paxton 4
126 !% M Methfessel and AT Paxton, <i>Phys. Rev. B</i> <b>40</b>, 3616 (1989).
127 !% In this case, the variable <tt>SmearingMPOrder</tt> sets the order of the smearing.
128 !% Occupations may be negative.
129 !%Option spline_smearing 5
130 !% Nearly identical to Gaussian smearing.
131 !% JM Holender, MJ Gillan, MC Payne, and AD Simpson, <i>Phys. Rev. B</i> <b>52</b>, 967 (1995).
132 !%Option gaussian_smearing
133 !% Gaussian smearing.
134 !%Option lorentzian_smearing
135 !% Lorentzian smearing.
136 !%Option tetrahedra
137 !% Linear tetrahedron method as in P. E. Bloechl, et al., <i>Phys. Rev. B</i> <b>49</b>, 16223 (1994).
138 !% Requires a regular Monkhorst-Pack generated by Octopus.
139 !%Option tetrahedra_opt
140 !% Improved tetrahedron method as in M. Kawamura, et al., <i>Phys. Rev. B</i> <b>89</b>, 094515 (2014).
141 !% Requires a regular Monkhorst-Pack generated by Octopus.
142 !%End
143 if (fixed_occ) then
144 this%method = smear_fixed_occ
145 else
146 call parse_variable(namespace, 'SmearingFunction', smear_semiconductor, this%method)
147 if (.not. varinfo_valid_option('SmearingFunction', this%method)) call messages_input_error(namespace, 'SmearingFunction')
148 call messages_print_var_option('SmearingFunction', this%method, namespace=namespace)
149 end if
151 !%Variable Smearing
152 !%Type float
153 !%Default 0.1 eV
154 !%Section States
155 !%Description
156 !% If <tt>Occupations</tt> is not set, <tt>Smearing</tt> is the
157 !% smearing width used in the <tt>SmearingFunction</tt> to distribute the electrons
158 !% among the existing states.
159 !%End
160 this%dsmear = 1e-14_real64
161 if (this%method /= smear_semiconductor .and. this%method /= smear_fixed_occ) then
162 call parse_variable(namespace, 'Smearing', 0.1_real64 / (m_two * p_ry), this%dsmear, units_inp%energy)
163 end if
165 !%Variable PhotoDopingSmearing
166 !%Type float
167 !%Default 0.1 eV
168 !%Section States
169 !%Description
170 !% If <tt>Occupations</tt> is not set, <tt>PhotoDopingSmearing</tt> is the
171 !% smearing width used in the <tt>SmearingFunction</tt> to distribute the electrons in conduction bands
172 !% among the existing states.
173 !%End
174 this%dsmear_cond = this%dsmear
175 if (this%method /= smear_semiconductor .and. this%method /= smear_fixed_occ) then
176 call parse_variable(namespace, 'PhotoDopingSmearing', 0.1_real64 / (m_two * p_ry), this%dsmear_cond, units_inp%energy)
177 end if
178
179 !%Variable PhotoDopingNumElectrons
180 !%Type float
181 !%Default 0
182 !%Section States
183 !%Description
184 !% This variable allows to set the number of valence electrons taken out to put
185 !% into the conduction bands. The method follows Marini and Calandra, PRB 104, 144103 (2021).
186 !%End
187 call parse_variable(namespace, 'PhotoDopingNumElectrons', m_zero, this%nephotodop)
189 if (this%nephotodop > m_min_occ) then
190 this%photodop=.true.
191 else
192 this%photodop=.false.
193 endif
194
195
196 !%Variable PhotoDopingBand
197 !%Type integer
198 !%Default 1
199 !%Section States
200 !%Description
201 !% This variable specifies where the minium (starting) conduction band index for the photodoping electrons.
202 !%End
203 call parse_variable(namespace, 'PhotoDopingBand', 1, this%photodop_bandmin)
204
205
206 call messages_obsolete_variable(namespace, 'ElectronicTemperature', 'Smearing')
207
208 if (ispin == 1) then ! unpolarized
209 this%el_per_state = 2
210 else
211 this%el_per_state = 1
212 end if
213
214 if (ispin == 2) then
215 this%nspins = 2
216 else
217 this%nspins = 1
218 end if
219
220 if (this%method == smear_semiconductor) then
221 this%nik_factor = kpoints_kweight_denominator(kpoints)
222
223 if (this%nik_factor == 0) then
224 message(1) = "k-point weights in KPoints or KPointsReduced blocks must be rational numbers for semiconducting smearing."
225 call messages_fatal(1, namespace=namespace)
226 end if
227 else if (this%method == smear_tetrahedra .or. this%method == smear_tetrahedra_opt) then
228 if (.not. associated(kpoints%reduced%simplex)) then
229 message(1) = "Tetrahedron smearing requires a simplex mesh for the k-point grid."
230 call messages_fatal(1, namespace=namespace)
231 end if
232
233 this%tetra_simplex => kpoints%reduced%simplex
234 end if
235
236 this%MP_n = 0
237 if (this%method == smear_methfessel_paxton) then
238 !%Variable SmearingMPOrder
239 !%Type integer
240 !%Default 1
241 !%Section States
242 !%Description
243 !% Sets the order of the Methfessel-Paxton smearing function.
244 !%End
245 call parse_variable(namespace, 'SmearingMPOrder', 1, this%MP_n)
246 end if
247
248 pop_sub(smear_init)
249 end subroutine smear_init
250
251
252 !--------------------------------------------------
253 subroutine smear_copy(to, from)
254 type(smear_t), intent(out) :: to
255 type(smear_t), intent(in) :: from
256
257 push_sub(smear_copy)
258
259 to%method = from%method
260 to%dsmear = from%dsmear
261 to%e_fermi = from%e_fermi
262 to%el_per_state = from%el_per_state
263 to%ef_occ = from%ef_occ
264 to%MP_n = from%MP_n
265 to%fermi_count = from%fermi_count
266 to%nik_factor = from%nik_factor
267 to%tetra_simplex => from%tetra_simplex
268
269 to%dsmear_cond = from%dsmear_cond
270 to%e_fermi_cond = from%e_fermi_cond
271 to%ef_occ_cond = from%ef_occ_cond
272 to%integral_occs = from%integral_occs
273 to%nspins = from%nspins
274 to%photodop = from%photodop
275 to%nephotodop = from%nephotodop
276 to%photodop_bandmin = from%photodop_bandmin
277
278 pop_sub(smear_copy)
279 end subroutine smear_copy
280
281
282 !--------------------------------------------------
283 subroutine smear_find_fermi_energy(this, namespace, eigenvalues, occupations, &
284 qtot, nik, nst, kweights)
285 type(smear_t), intent(inout) :: this
286 type(namespace_t), intent(in) :: namespace
287 real(real64), intent(in) :: eigenvalues(:,:), occupations(:,:)
288 real(real64), intent(in) :: qtot, kweights(:)
289 integer, intent(in) :: nik, nst
290
291 real(real64), parameter :: tol = 1.0e-10_real64
292 integer :: ist, ik, iter, maxq, weight, sumq_int, sum_weight
293 real(real64) :: sumq_frac
294 logical :: conv
295 real(real64), allocatable :: eigenval_list(:)
296 integer, allocatable :: k_list(:), reorder(:)
297 integer :: fermi_count_up, fermi_count_down
298
300
301 maxq = this%el_per_state * nst * this%nspins
302 if (maxq - qtot <= -tol) then ! not enough states
303 message(1) = 'Not enough states'
304 write(message(2),'(6x,a,f12.6,a,i10)')'(total charge = ', qtot, &
305 ' max charge = ', maxq
306 call messages_fatal(2, namespace=namespace)
307 end if
308
309 conv = .true.
310 if (this%method == smear_fixed_occ) then ! Fermi energy: last of occupied states
311 ist_cycle: do ist = nst, 1, -1
312 if (any(occupations(ist, :) > m_min_occ)) then
313 this%e_fermi = eigenvalues(ist, 1)
314 this%ef_occ = occupations(ist, 1) / this%el_per_state
315 do ik = 2, nik
316 if (eigenvalues(ist, ik) > this%e_fermi .and. occupations(ist, ik) > m_min_occ) then
317 this%e_fermi = eigenvalues(ist, ik)
318 this%ef_occ = occupations(ist, ik) / this%el_per_state
319 end if
320 end do
321 exit ist_cycle
322 end if
323 end do ist_cycle
324
325 else if (this%method == smear_semiconductor) then
326 ! first we sort the eigenvalues
327 safe_allocate(eigenval_list(1:nst * nik))
328 safe_allocate( k_list(1:nst * nik))
329 safe_allocate( reorder(1:nst * nik))
330
331 iter = 1
332 do ist = 1, nst
333 do ik = 1, nik
334 eigenval_list(iter) = eigenvalues(ist, ik)
335 k_list(iter) = ik
336 reorder(iter) = iter
337 iter = iter + 1
338 end do
339 end do
340
341 call sort(eigenval_list, reorder)
342
343 sumq_int = floor(qtot) * this%nik_factor
344 sumq_frac = qtot * this%nik_factor - sumq_int
345 if ( sumq_frac + tol > this%nik_factor ) then
346 sumq_int = sumq_int + this%nik_factor
347 sumq_frac = sumq_frac - this%nik_factor
348 end if
349 if (sumq_frac < tol) sumq_frac = m_zero
350
351 do iter = 1, nst * nik
352 weight = int(kweights(k_list(reorder(iter))) * this%nik_factor + m_half)
353 if (weight <= 0) cycle
354 this%e_fermi = eigenval_list(iter)
355 this%ef_occ = (sumq_int + sumq_frac) / (weight * this%el_per_state)
356
357 if (sumq_int - weight * this%el_per_state <= 0) then
358 ! count how many occupied states are at the fermi level,
359 ! this is required later to fill the states
360 this%fermi_count = 1
361 fermi_count_up = 1
362 fermi_count_down = 1
363 sum_weight = weight
364 do
365 if (iter - fermi_count_down < 1) exit
366 if (abs(this%e_fermi - eigenval_list(iter - fermi_count_down)) > tol_smear) exit
367 weight = int(kweights(k_list(reorder(iter - fermi_count_down))) * this%nik_factor + m_half)
368 if (weight > 0) then
369 sumq_int = sumq_int + weight * this%el_per_state
370 sum_weight = sum_weight + weight
371 end if
372 fermi_count_down = fermi_count_down + 1
373 end do
374 do
375 if (iter + fermi_count_up > nst*nik) exit
376 if (abs(this%e_fermi - eigenval_list(iter + fermi_count_up)) > tol_smear) exit
377 weight = int(kweights(k_list(reorder(iter + fermi_count_up))) * this%nik_factor + m_half)
378 if (weight > 0) then
379 sum_weight = sum_weight + weight
380 end if
381 fermi_count_up = fermi_count_up + 1
382 end do
383 this%fermi_count = fermi_count_up + fermi_count_down - 1
384 this%ef_occ = (sumq_int + sumq_frac) / (sum_weight * this%el_per_state)
385 exit
386 end if
387
388 sumq_int = sumq_int - weight * this%el_per_state
389 end do
390 assert(this%ef_occ < m_one + 10.0_real64*m_epsilon)
391
392 safe_deallocate_a(eigenval_list)
393 safe_deallocate_a(k_list)
394 safe_deallocate_a(reorder)
395
396 else if (this%method == smear_tetrahedra .or. this%method == smear_tetrahedra_opt) then
397 if (this%photodop) then
398 call messages_not_implemented('Photodoping for SmearingFunction = tetrahedra/tetrahedra_opt')
399 end if
400 call bisection_find_fermi_energy_tetra(this, namespace, tol, eigenvalues, nik, nst, qtot, this%e_fermi)
401 else ! bisection
402 if (this%photodop) then
403 ! find fermi energy for valence electrons
404 call bisection_find_fermi_energy(this, namespace, this%dsmear, tol, &
405 eigenvalues, kweights, nik, qtot-this%nephotodop, 1, this%photodop_bandmin-1, &
406 this%e_fermi, this%ef_occ)
407
408 ! find fermi energy for conduction electrons
409 call bisection_find_fermi_energy(this, namespace, this%dsmear_cond, tol, &
410 eigenvalues, kweights, nik, this%nephotodop, this%photodop_bandmin, nst, &
411 this%e_fermi_cond, this%ef_occ_cond)
412 else
413 call bisection_find_fermi_energy(this, namespace, this%dsmear, tol, &
414 eigenvalues, kweights, nik, qtot, 1, nst, this%e_fermi, this%ef_occ)
415 end if
416 end if
417
419 end subroutine smear_find_fermi_energy
420
421 ! ---------------------------------------------------------
422 subroutine bisection_find_fermi_energy(this, namespace, dsmear_in, tol, &
423 eigenvalues, kweights, nik, q_in, start_band, end_band, e_fermi, ef_occ)
424 type(smear_t), intent(inout) :: this
425 type(namespace_t), intent(in) :: namespace
426 real(real64), intent(in) :: dsmear_in
427 real(real64), intent(in) :: tol
428 integer, intent(in) :: nik
429 real(real64), intent(in) :: eigenvalues(:,:)
430 real(real64), intent(in) :: kweights(:), q_in
431 integer, intent(in) :: start_band, end_band
432 real(real64), intent(out) :: e_fermi, ef_occ
433
434 integer, parameter :: nitmax = 200
435 integer :: ist, ik, iter
436 real(real64) :: drange, dsmear, emin, emax, xx, sumq
437 logical :: conv
438
440
441 dsmear = max(1e-14_real64, dsmear_in)
442 drange = dsmear * sqrt(-log(tol * 0.01_real64))
443
444 emin = minval(eigenvalues) - drange
445 emax = maxval(eigenvalues) + drange
446
447 do iter = 1, nitmax
448 e_fermi = m_half * (emin + emax)
449 sumq = m_zero
450
451 do ik = 1, nik
452 do ist = start_band, end_band
453 xx = (e_fermi - eigenvalues(ist, ik))/dsmear
454 sumq = sumq + kweights(ik) * this%el_per_state * &
455 smear_step_function(this, xx)
456 end do
457 end do
458
459 conv = (abs(sumq - q_in) <= tol)
460 if (conv) exit
461
462 if (sumq <= q_in) emin = e_fermi
463 if (sumq >= q_in) emax = e_fermi
464
465 ef_occ = smear_step_function(this, m_zero)
466 end do
467
468 if (.not. conv) then
469 message(1) = 'Fermi: did not converge.'
470 call messages_fatal(1, namespace=namespace)
471 end if
472
474 end subroutine bisection_find_fermi_energy
475
476 ! ---------------------------------------------------------
496 subroutine bisection_find_fermi_energy_tetra(this, namespace, tol, eigenvalues, nik, nst, q_in, e_fermi)
497 type(smear_t), intent(inout) :: this
498 type(namespace_t), intent(in) :: namespace
499 real(real64), intent(in) :: tol
500 integer, intent(in) :: nik, nst
501 real(real64), intent(in) :: eigenvalues(:,:)
502 real(real64), intent(in) :: q_in
503 real(real64), intent(out) :: e_fermi
504
505 integer, parameter :: nitmax = 200
506 integer :: iter
507 real(real64) :: emin, emax, sumq
508 logical :: conv
509
510 integer :: ist, ii, ll, is, ik, ns, nik_red, nvertices
511 real(real64) :: e_simplex(20), w_simplex(4), dos_simplex(4)
512
513 push_sub_with_profile(bisection_find_fermi_energy_tetra)
514
515 assert(associated(this%tetra_simplex))
516 assert(this%tetra_simplex%n_simplices > 0)
517 assert(this%tetra_simplex%sdim > 0)
518
519 ns = this%nspins
520 assert(ns > 0)
521 assert(mod(nik, ns) == 0)
522
523 nik_red = nik / ns
524 assert(maxval(this%tetra_simplex%simplices) <= nik_red)
525
526 nvertices = this%tetra_simplex%rdim + 1
527 assert(nvertices > 0)
528 assert(nvertices <= this%tetra_simplex%sdim)
529
530 emin = minval(eigenvalues)
531 emax = maxval(eigenvalues)
532 if (.not. (emin < emax)) then
533 write(message(1), '(a)') 'Tetra bisection: invalid energy bracket from eigenvalues.'
534 call messages_fatal(1, namespace=namespace)
535 end if
536
537 do iter = 1, nitmax
538 e_fermi = m_half * (emin + emax)
539 sumq = m_zero
540 !$omp parallel do collapse(2) private(ist, ii, is, ll, ik, e_simplex, w_simplex, dos_simplex) reduction(+:sumq)
541 do ist = 1, nst
542 do ii = 1, this%tetra_simplex%n_simplices
543 do is = 0, ns - 1
544 do ll = 1, this%tetra_simplex%sdim
545 ik = ns * (this%tetra_simplex%simplices(ii, ll) - 1) + 1
546 e_simplex(ll) = eigenvalues(ist, ik + is)
547 end do
548 w_simplex(:) = m_zero
549
550 call simplex_weights(this%tetra_simplex%rdim, e_simplex(1:this%tetra_simplex%sdim), e_fermi, &
551 w_simplex(1:nvertices), dos_simplex(1:nvertices))
552
553 do ll = 1, nvertices
554 sumq = sumq + this%el_per_state * w_simplex(ll) / this%tetra_simplex%n_points
555 end do
556 end do
557 end do
558 end do
559 !$omp end parallel do
560
561 conv = (abs(sumq - q_in) <= tol)
562 if (conv) exit
563
564 if (sumq <= q_in) emin = e_fermi
565 if (sumq >= q_in) emax = e_fermi
566 end do
567
568 if (.not. conv) then
569 message(1) = 'Fermi (tetrahedra): did not converge.'
570 call messages_fatal(1, namespace=namespace)
571 end if
572
573 pop_sub_with_profile(bisection_find_fermi_energy_tetra)
575
576 ! ---------------------------------------------------------
577 subroutine smear_fill_occupations(this, eigenvalues, occupations, kweights, nik, nst)
578 type(smear_t), intent(in) :: this
579 real(real64), intent(in) :: eigenvalues(:,:)
580 real(real64), intent(inout) :: occupations(:,:)
581 real(real64), intent(in) :: kweights(:)
582 integer, intent(in) :: nik, nst
583
584 integer :: ik, ist, ifermi
585 real(real64) :: dsmear, xx, dsmear_cond
586
587 push_sub(smear_fill_occupations)
588
589 if (this%method == smear_fixed_occ) then
590 ! do nothing
591 else if (this%method == smear_semiconductor) then
592 assert(this%fermi_count > 0 .and. this%fermi_count <= nik*nst)
593
594 ifermi = 0
595 do ik = 1, nik
596 do ist = 1, nst
597 xx = eigenvalues(ist, ik) - this%e_fermi
598 if (xx < -tol_smear) then
599 occupations(ist, ik) = this%el_per_state
600 else if (abs(xx) <= tol_smear .and. ifermi < this%fermi_count) then
601 occupations(ist, ik) = this%ef_occ * this%el_per_state
602 ifermi = ifermi + 1
603 else
604 occupations(ist, ik) = m_zero
605 end if
606
607 end do
608 end do
609 else if (this%method == smear_tetrahedra .or. this%method == smear_tetrahedra_opt) then
610 if (this%photodop) then
611 call messages_not_implemented('Photodoping for SmearingFunction = tetrahedra/tetrahedra_opt')
612 end if
613 block
614 integer :: ii, ll, is, ns, nik_red, nvertices
615 real(real64) :: e_simplex(20), w_simplex(4), dos_simplex(4)
616
617 assert(associated(this%tetra_simplex))
618 assert(this%tetra_simplex%n_simplices > 0)
619 assert(this%tetra_simplex%sdim > 0)
620
621 ns = this%nspins
622 assert(ns > 0)
623 assert(mod(nik, ns) == 0)
624
625 nik_red = nik / ns
626 assert(maxval(this%tetra_simplex%simplices) <= nik_red)
627
628 nvertices = this%tetra_simplex%rdim + 1
629 assert(nvertices > 0)
630 assert(nvertices <= this%tetra_simplex%sdim)
631
632 occupations(:, :) = m_zero
633 !$omp parallel do collapse(2) private(ist, ii, is, ll, ik, e_simplex, w_simplex, dos_simplex) reduction(+:occupations)
634 do ist = 1, nst
635 do ii = 1, this%tetra_simplex%n_simplices
636 do is = 0, ns - 1
637 do ll = 1, this%tetra_simplex%sdim
638 ik = ns * (this%tetra_simplex%simplices(ii, ll) - 1) + 1
639 e_simplex(ll) = eigenvalues(ist, ik + is)
640 end do
641 w_simplex(:) = m_zero
642
643 call simplex_weights(this%tetra_simplex%rdim, e_simplex(1:this%tetra_simplex%sdim), this%e_fermi, &
644 w_simplex(1:nvertices), dos_simplex(1:nvertices))
645
646 do ll = 1, nvertices
647 ik = ns * (this%tetra_simplex%simplices(ii, ll) - 1) + 1
648 assert(kweights(ik + is) > m_epsilon)
649 occupations(ist, ik + is) = occupations(ist, ik + is) + this%el_per_state * &
650 w_simplex(ll) / (this%tetra_simplex%n_points * kweights(ik + is))
651 end do
652 end do
653 end do
654 end do
655 !$omp end parallel do
656 end block
657 else
658 dsmear = max(1e-14_real64, this%dsmear)
659 if (this%photodop) then
660 dsmear_cond = max(1e-14_real64, this%dsmear_cond)
661 do ik = 1, nik
662 do ist = 1, nst
663 if (ist < this%photodop_bandmin) then
664 ! valence electrons
665 xx = (this%e_fermi - eigenvalues(ist, ik))/dsmear
666 else
667 ! conduction electrons
668 xx = (this%e_fermi_cond - eigenvalues(ist, ik))/dsmear_cond
669 end if
670 occupations(ist, ik) = smear_step_function(this, xx) * this%el_per_state
671 end do
672 end do
673 else
674 do ik = 1, nik
675 do ist = 1, nst
676 xx = (this%e_fermi - eigenvalues(ist, ik))/dsmear
677 occupations(ist, ik) = smear_step_function(this, xx) * this%el_per_state
678 end do
679 end do
680 end if
681 end if
682
684 end subroutine smear_fill_occupations
685
686 !--------------------------------------------------
687 real(real64) function smear_calc_entropy(this, eigenvalues, &
688 nik, nst, kweights, occ) result(entropy)
689 type(smear_t), intent(in) :: this
690 real(real64), intent(in) :: eigenvalues(:,:)
691 real(real64), intent(in) :: kweights(:)
692 integer, intent(in) :: nik, nst
693 real(real64), intent(in) :: occ(:, :)
694
695 integer :: ist, ik
696 real(real64) :: dsmear, xx, term, ff
697
698 push_sub(smear_calc_entropy)
699
700 entropy = m_zero
701
702 if (this%method == smear_fixed_occ .or. this%method == smear_semiconductor) then
703 ! Fermi-Dirac entropy, not quite the same as will be obtained with true smearing
704 ! RM Wentzcovitch, JL Martins, and PB Allen, Phys. Rev. B 45, 11372 (1992) eqn (5)
705 ! also N Marzari PhD thesis p 117, http://quasiamore.mit.edu/phd/Marzari_PhD.pdf
706 do ik = 1, nik
707 do ist = 1, nst
708 ff = occ(ist, ik) / this%el_per_state
709 if (ff > m_zero .and. ff < m_one) then
710 term = ff * log(ff) + (1 - ff) * log(1 - ff)
711 else ! we have semiconducting smearing, or perverse occupations as in Methfessel-Paxton
712 term = m_zero
713 end if
714 entropy = entropy - kweights(ik) * this%el_per_state * term
715 end do
716 end do
717 else
718 dsmear = max(1e-14_real64, this%dsmear)
719
720 do ik = 1, nik
721 do ist = 1, nst
722 if (eigenvalues(ist, ik) < huge(m_one)) then
723 xx = (this%e_fermi - eigenvalues(ist, ik)) / dsmear
724 entropy = entropy - kweights(ik) * this%el_per_state * &
725 smear_entropy_function(this, xx)
726 end if
727 end do
728 end do
729 end if
730
731 pop_sub(smear_calc_entropy)
732 end function smear_calc_entropy
733
734
735 ! ---------------------------------------------------------
736 real(real64) function smear_delta_function(this, xx) result(deltaf)
737 type(smear_t), intent(in) :: this
738 real(real64), intent(in) :: xx
739
740 real(real64), parameter :: maxarg = 200.0_real64
741 real(real64) :: xp, arg, hd, hp, aa
742 integer :: ii, ni
743
744 ! no PUSH_SUB, called too often
745
746 ! smear_delta_function is not defined for SMEAR_FIXED_OCC
747 assert(this%method /= smear_fixed_occ)
748
749 deltaf = m_zero
750 select case (this%method)
752 if (abs(xx) <= m_epsilon) then
753 deltaf = this%ef_occ
754 end if
755
756 case (smear_fermi_dirac)
757 if (abs(xx) <= 36.0_real64) then
758 deltaf = m_one / (m_two + exp(-xx) + exp(xx))
759 end if
760
761 case (smear_cold)
762 xp = xx - m_one / sqrt(m_two)
763 arg = min(maxarg, xp**2)
764
765 deltaf = exp(-arg) / sqrt(m_pi) * (m_two - sqrt(m_two) * xx)
766
768 arg = min(maxarg, xx**2)
769 deltaf = exp(-arg) / sqrt(m_pi)
770
771 if (this%MP_n > 0) then ! recursion
772 hd = m_zero
773 hp = exp(-arg)
774 ni = 0
775 aa = m_one / sqrt(m_pi)
776 do ii = 1, this%MP_n
777 hd = m_two * xx * hp - m_two * ni * hd
778 ni = ni + 1
779 aa = -aa / (m_four * ii)
780 hp = m_two * xx * hd - m_two * ni * hp
781 ni = ni + 1
782 deltaf = deltaf + aa * hp
783 end do
784 end if
785
786 case (smear_spline)
787 xp = abs(xx) + m_one / sqrt(m_two)
788 deltaf = sqrt(m_e) * xp * exp(-xp * xp)
789
790 case (smear_gaussian)
791 deltaf = exp(-xx * xx) / sqrt(m_pi)
792
793 case (smear_lorentzian)
794 deltaf = m_one / (m_pi * (xx * xx + m_one))
795
796 end select
797
798 end function smear_delta_function
799
800
801 ! ---------------------------------------------------------
802 real(real64) function smear_step_function(this, xx) result(stepf)
803 type(smear_t), intent(in) :: this
804 real(real64), intent(in) :: xx
805
806 real(real64), parameter :: maxarg = 200.0_real64
807 real(real64) :: xp, arg, hd, hp, aa
808 integer :: ii, ni
809
810 push_sub(smear_step_function)
811
812 ! smear_step_function is not defined for SMEAR_FIXED_OCC
813 assert(this%method /= smear_fixed_occ)
814
815 stepf = m_zero
816 select case (this%method)
818 if (xx > m_zero) then
819 stepf = m_one
820 else if (abs(xx) <= m_epsilon) then
821 stepf = this%ef_occ
822 end if
823
824 case (smear_fermi_dirac)
825 if (xx > maxarg) then
826 stepf = m_one
827 else if (xx > -maxarg) then
828 stepf = m_one / (m_one + exp(-xx))
829 end if
830
832 xp = xx - m_one / sqrt(m_two)
833 arg = min(maxarg, xp**2)
834
835 stepf = m_half * erf(xp) + &
836 m_one / sqrt(m_two * m_pi) * exp(-arg) + m_half
837
839 stepf = m_half * erfc(-xx)
840
841 if (this%MP_n > 0) then ! recursion
842 hd = m_zero
843 arg = min(maxarg, xx**2)
844 hp = exp(-arg)
845 ni = 0
846 aa = m_one / sqrt(m_pi)
847 do ii = 1, this%MP_n
848 hd = m_two * xx * hp - m_two * ni * hd
849 ni = ni + 1
850 aa = -aa / (m_four * ii)
851 stepf = stepf - aa * hd
852 hp = m_two * xx * hd - m_two * ni * hp
853 ni = ni + 1
854 end do
855 end if
856
857 case (smear_spline)
858 if (xx <= m_zero) then
859 xp = xx - m_one / sqrt(m_two)
860 stepf = m_half * sqrt(m_e) * exp(-xp * xp)
861 else
862 xp = xx + m_one / sqrt(m_two)
863 stepf = m_one - m_half * sqrt(m_e) * exp(-xp * xp)
864 end if
865
866 case (smear_gaussian)
867 stepf = m_half * erfc(-xx)
868
869 case (smear_lorentzian)
870 stepf = atan(xx) / m_pi + m_half
871
872 end select
873
874 pop_sub(smear_step_function)
875 end function smear_step_function
876
877
878 ! ---------------------------------------------------------
880 real(real64) function smear_entropy_function(this, xx) result(entropyf)
881 type(smear_t), intent(in) :: this
882 real(real64), intent(in) :: xx
883
884 real(real64), parameter :: maxarg = 200.0_real64
885 real(real64) :: xp, arg, hd, hp, hpm1, aa
886 integer :: ii, ni
887
888 push_sub(smear_entropy_function)
889
890 ! smear_entropy_function is not defined for SMEAR_FIXED_OCC
891 assert(this%method /= smear_fixed_occ)
892
893 entropyf = m_zero
894 select case (this%method)
896
898 if (abs(xx) <= 36.0_real64) then
899 xp = m_one / (m_one + exp(-xx))
900 entropyf = xp * log(xp) + (m_one - xp) * log(m_one - xp)
901 end if
902
903 case (smear_cold)
904 xp = xx - m_one / sqrt(m_two)
905 arg = min(maxarg, xp**2)
906
907 entropyf = m_one / sqrt(m_two * m_pi) * xp * exp(-arg)
908
910 arg = min(maxarg, xx**2)
911 entropyf = -m_half * exp(-arg) / sqrt(m_pi)
912
913 if (this%MP_n > 0) then ! recursion
914 hd = m_zero
915 hp = exp(-arg)
916 ni = 0
917 aa = m_one / sqrt(m_pi)
918 do ii = 1, this%MP_n
919 hd = m_two * xx * hp - m_two * ni * hd
920 ni = ni + 1
921 hpm1 = hp
922 hp = m_two * xx * hd - m_two * ni * hp
923 ni = ni + 1
924 aa = -aa / (m_four * ii)
925 entropyf = entropyf - aa * (m_half * hp + hpm1 * ni)
926 end do
927 end if
928
929 case (smear_spline)
930 xp = abs(xx) + m_one / sqrt(m_two)
931 entropyf = -sqrt(m_e) * (abs(xx) * exp(-xp * xp) / m_two + sqrt(m_pi) / m_four * erfc(xp))
932
933 case (smear_gaussian)
934 entropyf = -exp(-xx * xx) / m_two / sqrt(m_pi)
935
936 case (smear_lorentzian)
937 entropyf = m_ninf
938
939 end select
940
942 end function smear_entropy_function
943
944
945 ! ---------------------------------------------------------
946 logical pure function smear_is_semiconducting(this) result(answer)
947 type(smear_t), intent(in) :: this
948
949 answer = this%method == smear_semiconductor
950
951 end function smear_is_semiconducting
952
953 subroutine smear_write_info(this, namespace, iunit)
954 type(smear_t), intent(in) :: this
955 type(namespace_t), intent(in) :: namespace
956 integer, optional, intent(in) :: iunit
957
958
959 if (this%method /= smear_semiconductor .and. this%method /= smear_fixed_occ) then
960 if (this%photodop) then
961 write(message(1), '(a,f12.6,1x,a)') "Fermi energy (valence ) = ", &
962 units_from_atomic(units_out%energy, this%e_fermi), units_abbrev(units_out%energy)
963 write(message(2), '(a,f12.6,1x,a)') "Fermi energy (conduction) = ", &
964 units_from_atomic(units_out%energy, this%e_fermi_cond), units_abbrev(units_out%energy)
965 call messages_info(2, iunit=iunit, namespace=namespace)
966 else
967 write(message(1), '(a,f12.6,1x,a)') "Fermi energy = ", &
968 units_from_atomic(units_out%energy, this%e_fermi), units_abbrev(units_out%energy)
969 call messages_info(1, iunit=iunit, namespace=namespace)
970 end if
971 end if
972
973 end subroutine smear_write_info
974
976end module smear_oct_m
977
978!! Local Variables:
979!! mode: f90
980!! coding: utf-8
981!! End:
This is the common interface to a sorting routine. It performs the shell algorithm,...
Definition: sort.F90:156
double log(double __x) __attribute__((__nothrow__
double exp(double __x) __attribute__((__nothrow__
double atan(double __x) __attribute__((__nothrow__
double sqrt(double __x) __attribute__((__nothrow__
double floor(double __x) __attribute__((__nothrow__
real(real64), parameter, public m_two
Definition: global.F90:202
real(real64), parameter, public m_zero
Definition: global.F90:200
real(real64), parameter, public p_ry
Definition: global.F90:239
real(real64), parameter, public m_epsilon
Definition: global.F90:216
real(real64), parameter, public m_half
Definition: global.F90:206
real(real64), parameter, public m_one
Definition: global.F90:201
real(real64), parameter, public m_min_occ
Minimal occupation that is considered to be non-zero.
Definition: global.F90:227
integer function, public kpoints_kweight_denominator(this)
Definition: kpoints.F90:1802
subroutine, public messages_not_implemented(feature, namespace)
Definition: messages.F90:1068
subroutine, public messages_obsolete_variable(namespace, name, rep)
Definition: messages.F90:1000
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_fatal(no_lines, only_root_writes, namespace)
Definition: messages.F90:410
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:691
integer, parameter, public smear_tetrahedra_opt
Definition: smear.F90:176
real(real64) function, public smear_calc_entropy(this, eigenvalues, nik, nst, kweights, occ)
Definition: smear.F90:784
integer, parameter, public smear_tetrahedra
Definition: smear.F90:176
subroutine, public smear_find_fermi_energy(this, namespace, eigenvalues, occupations, qtot, nik, nst, kweights)
Definition: smear.F90:380
real(real64) function, public smear_entropy_function(this, xx)
This function is defined as .
Definition: smear.F90:976
real(real64) function, public smear_delta_function(this, xx)
Definition: smear.F90:832
integer, parameter, public smear_fermi_dirac
Definition: smear.F90:176
subroutine bisection_find_fermi_energy_tetra(this, namespace, tol, eigenvalues, nik, nst, q_in, e_fermi)
Finds the Fermi energy using the tetrahedron method via bisection.
Definition: smear.F90:592
integer, parameter, public smear_methfessel_paxton
Definition: smear.F90:176
subroutine, public smear_write_info(this, namespace, iunit)
Definition: smear.F90:1049
real(real64) function, public smear_step_function(this, xx)
Definition: smear.F90:898
integer, parameter, public smear_semiconductor
Definition: smear.F90:176
subroutine, public smear_fill_occupations(this, eigenvalues, occupations, kweights, nik, nst)
Definition: smear.F90:673
integer, parameter, public smear_lorentzian
Definition: smear.F90:176
subroutine, public smear_copy(to, from)
Definition: smear.F90:349
integer, parameter, public smear_fixed_occ
Definition: smear.F90:176
integer, parameter, public smear_spline
Definition: smear.F90:176
subroutine bisection_find_fermi_energy(this, namespace, dsmear_in, tol, eigenvalues, kweights, nik, q_in, start_band, end_band, e_fermi, ef_occ)
Definition: smear.F90:519
subroutine, public smear_init(this, namespace, ispin, fixed_occ, integral_occs, kpoints)
Definition: smear.F90:194
integer, parameter, public smear_cold
Definition: smear.F90:176
logical pure function, public smear_is_semiconducting(this)
Definition: smear.F90:1042
integer, parameter, public smear_gaussian
Definition: smear.F90:176
This module is intended to contain "only mathematical" functions and procedures.
Definition: sort.F90:119
brief This module defines the class unit_t which is used by the unit_systems_oct_m module.
Definition: unit.F90:134
This module defines the unit system, used for input and output.
type(unit_system_t), public units_inp
the units systems for reading and writing
int true(void)