SIRIUS 7.5.0
Electronic structure library and applications
smearing.hpp
Go to the documentation of this file.
1// Copyright (c) 2013-2018 Anton Kozhevnikov, Thomas Schulthess
2// All rights reserved.
3//
4// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
5// the following conditions are met:
6//
7// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
8// following disclaimer.
9// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
10// and the following disclaimer in the documentation and/or other materials provided with the distribution.
11//
12// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
13// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
14// PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
15// ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
16// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
17// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
18// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19
20/** \file smearing.hpp
21 *
22 * \brief Smearing functions used in finding the band occupancies.
23 */
24
25#ifndef __SMEARING_HPP__
26#define __SMEARING_HPP__
27
28#include <functional>
29#include <string>
30#include <stdexcept>
31#include <map>
32#include <sstream>
33#include <algorithm>
34
35namespace sirius {
36
37/// Occupancy smearing functions.
38namespace smearing {
39
40enum class smearing_t
41{
42 gaussian,
43 fermi_dirac,
44 cold,
45 methfessel_paxton
46};
47
48inline smearing_t
49get_smearing_t(std::string name__)
50{
51 std::transform(name__.begin(), name__.end(), name__.begin(), ::tolower);
52 std::map<std::string, smearing_t> const m = {
53 {"gaussian", smearing_t::gaussian},
54 {"fermi_dirac", smearing_t::fermi_dirac},
55 {"cold", smearing_t::cold},
56 {"methfessel_paxton", smearing_t::methfessel_paxton},
57 };
58
59 if (m.count(name__) == 0) {
60 std::stringstream s;
61 s << "get_smearing_t(): wrong label of the smearing_t enumerator: " << name__;
62 throw std::runtime_error(s.str());
63 }
64 return m.at(name__);
65}
66
68{
69 static double delta(double x__, double width__);
70 static double occupancy(double x__, double width__);
71 static double entropy(double x__, double width__);
72};
73
75{
76 static double dxdelta(double x__, double width__);
77 static double delta(double x__, double width__);
78 static double occupancy(double x__, double width__);
79 static double entropy(double x__, double width__);
80};
81
82struct cold
83{
84 static double delta(double x__, double width__);
85 static double occupancy(double x__, double width__);
86 static double entropy(double x__, double width__);
87
88 /** Second derivative of the occupation function \f$f(x,w)\f$.
89 * \f[
90 * \frac{\partial^2 f(x,w)}{\partial x^2} = \frac{e^{-y^2} \left(2 \sqrt{2} y^2-2 y-\sqrt{2}\right)}{\sqrt{\pi }
91 * w^2}, \qquad y=\frac{x}{w} - \frac{1}{\sqrt{2}} \f]
92 */
93 static double dxdelta(double x__, double width__);
94};
95
96/** Methfessel-Paxton smearing.
97 *
98 * Methfessel, M., & Paxton, High-precision sampling for Brillouin-zone
99 * integration in metals. , 40(6), 3616–3621.
100 * http://dx.doi.org/10.1103/PhysRevB.40.3616
101 */
103{
104 static double dxdelta(double x__, double width__, int n__);
105 static double delta(double x__, double width__, int n__);
106 static double occupancy(double x__, double width__, int n__);
107 static double entropy(double x__, double width__, int n__);
108};
109
110inline std::function<double(double)>
111occupancy(smearing_t type__, double width__)
112{
113 switch (type__) {
114 case smearing_t::gaussian: {
115 return [width__](double x__) { return gaussian::occupancy(x__, width__); };
116 }
117 case smearing_t::fermi_dirac: {
118 return [width__](double x__) { return fermi_dirac::occupancy(x__, width__); };
119 }
120 case smearing_t::cold: {
121 return [width__](double x__) { return cold::occupancy(x__, width__); };
122 }
123 case smearing_t::methfessel_paxton: {
124 return [width__](double x__) { return methfessel_paxton::occupancy(x__, width__, 1); };
125 }
126 default: {
127 throw std::runtime_error("wrong type of smearing");
128 }
129 }
130}
131
132inline std::function<double(double)>
133entropy(smearing_t type__, double width__)
134{
135 switch (type__) {
136 case smearing_t::gaussian: {
137 return [width__](double x__) { return gaussian::entropy(x__, width__); };
138 }
139 case smearing_t::fermi_dirac: {
140 return [width__](double x__) { return fermi_dirac::entropy(x__, width__); };
141 }
142 case smearing_t::cold: {
143 return [width__](double x__) { return cold::entropy(x__, width__); };
144 }
145 case smearing_t::methfessel_paxton: {
146 return [width__](double x__) { return methfessel_paxton::entropy(x__, width__, 1); };
147 }
148 default: {
149 throw std::runtime_error("wrong type of smearing");
150 }
151 }
152}
153
154inline std::function<double(double)>
155delta(smearing_t type__, double width__)
156{
157 switch (type__) {
158 case smearing_t::gaussian: {
159 throw std::runtime_error("not available");
160 }
161 case smearing_t::fermi_dirac: {
162 return [width__](double x__) { return fermi_dirac::delta(x__, width__); };
163 }
164 case smearing_t::cold: {
165 return [width__](double x__) { return cold::delta(x__, width__); };
166 }
167 case smearing_t::methfessel_paxton: {
168 return [width__](double x__) { return methfessel_paxton::delta(x__, width__, 1); };
169 }
170 default: {
171 throw std::runtime_error("wrong type of smearing");
172 }
173 }
174}
175
176inline std::function<double(double)>
177dxdelta(smearing_t type__, double width__)
178{
179 switch (type__) {
180 case smearing_t::gaussian: {
181 throw std::runtime_error("not available");
182 }
183 case smearing_t::fermi_dirac: {
184 return [width__](double x__) { return fermi_dirac::dxdelta(x__, width__); };
185 }
186 case smearing_t::cold: {
187 return [width__](double x__) { return cold::dxdelta(x__, width__); };
188 }
189 case smearing_t::methfessel_paxton: {
190 return [width__](double x__) { return methfessel_paxton::dxdelta(x__, width__, 1); };
191 }
192 default: {
193 throw std::runtime_error("wrong type of smearing");
194 }
195 }
196}
197
198} // namespace smearing
199
200} // namespace sirius
201
202#endif
std::enable_if_t< std::is_same< T, real_type< F > >::value, void > transform(::spla::Context &spla_ctx__, sddk::memory_t mem__, la::dmatrix< F > const &M__, int irow0__, int jcol0__, real_type< F > alpha__, Wave_functions< T > const &wf_in__, spin_index s_in__, band_range br_in__, real_type< F > beta__, Wave_functions< T > &wf_out__, spin_index s_out__, band_range br_out__)
Apply linear transformation to the wave-functions.
Namespace of the SIRIUS library.
Definition: sirius.f90:5
static double dxdelta(double x__, double width__)
Definition: smearing.cpp:101
static double dxdelta(double x__, double width__)
Definition: smearing.cpp:64