Loading [MathJax]/extensions/TeX/AMSsymbols.js
SIRIUS 7.5.0
Electronic structure library and applications
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
hubbard.hpp
Go to the documentation of this file.
1// Copyright (c) 2013-2018 Mathieu Taillefumier, 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 hubbard.hpp
21 *
22 * \brief Contains declaration and partial implementation of sirius::Hubbard class.
23 */
24
25#ifndef __HUBBARD_HPP__
26#define __HUBBARD_HPP__
27
28#include <cstdio>
29#include <cstdlib>
31#include "k_point/k_point.hpp"
39#include "hubbard_matrix.hpp"
40
41namespace sirius {
42
43void generate_potential(Hubbard_matrix const& om__, Hubbard_matrix& um__);
44
45double energy(Hubbard_matrix const& om__);
46double one_electron_energy_hubbard(Hubbard_matrix const& om__, Hubbard_matrix const& pm__);
47
48/// Apply Hubbard correction in the collinear case
50{
51 private:
53
54 Unit_cell& unit_cell_;
55
56 /// Hubbard correction with next nearest neighbors
57 bool hubbard_U_plus_V_{false};
58
59 /// Hubbard with multi channels apply to both LDA+U+V case
60 bool multi_channels_{false};
61
62 void calculate_wavefunction_with_U_offset();
63
64 public:
65 /// Constructor.
67
68 /// Compute the occupancy derivatives with respect to atomic displacements.
69 /**
70 * To compute the occupancy derivatives, we first need to compute the derivatives of the matrix elements
71 * \f[
72 * \frac{\partial}{\partial {\bf r}_{\alpha}} \langle \phi_{i}^{Hub} | S | \psi_{j{\bf k}} \rangle
73 * \f]
74 * Let's first derive the case of non-orthogonalized Hubbard atomic orbitals. In this case
75 * \f[
76 * \frac{\partial}{\partial {\bf r}_{\alpha}} \langle \phi_{i}^{Hub} | S | \psi_{j{\bf k}} \rangle =
77 * \langle \frac{\partial}{\partial {\bf r}_{\alpha}} \phi_{i}^{Hub} | S | \psi_{j{\bf k}} \rangle +
78 * \langle \phi_{i}^{Hub} | \frac{\partial}{\partial {\bf r}_{\alpha}} S | \psi_{j{\bf k}} \rangle
79 * \f]
80 *
81 * Derivative \f$ \frac{\partial \phi_{i}}{\partial {\bf r}_{\alpha}} \f$ of the atomic functions
82 * is simple. For the wave-function of atom \f$ \alpha \f$ this is a multiplication of the plane-wave coefficients
83 * by \f$ {\bf G+k} \f$. For the rest of the atoms it is zero.
84 *
85 * Derivative of the S-operator has the following expression:
86 * \f[
87 * \frac{\partial}{\partial {\bf r}_{\alpha}} S =
88 * \sum_{\xi \xi'} |\frac{\partial}{\partial {\bf r}_{\alpha}} \beta_{\xi}^{\alpha} \rangle
89 * Q_{\xi \xi'}^{\alpha} \langle \beta_{\xi'}^{\alpha} | + |\beta_{\xi}^{\alpha}\rangle Q_{\xi \xi'}^{\alpha}
90 * \langle \frac{\partial}{\partial {\bf r}_{\alpha}} \beta_{\xi'}^{\alpha} |
91 * \f]
92 *
93 * Derivative of the inverse square root of the overlap matrix.
94 *
95 * Let's label \f$ \frac{\partial}{\partial {\bf r}_{\alpha}} {\bf O}^{-1/2} = {\bf X} \f$.
96 * From taking derivative of the identity
97 * \f[
98 * {\bf O}^{-1/2} {\bf O} {\bf O}^{-1/2}= {\bf I}
99 * \f]
100 * we get
101 * \f[
102 * {\bf X} {\bf O} {\bf O}^{-1/2} + {\bf O}^{-1/2}{\bf O}'{\bf O}^{-1/2} + {\bf O}^{-1/2}{\bf O}{\bf X} = 0
103 * \f]
104 * or simplifying
105 * \f[
106 * {\bf X} {\bf O}^{1/2} + {\bf O}^{1/2}{\bf X} = -{\bf O}^{-1/2}{\bf O}'{\bf O}^{-1/2}
107 * \f]
108 * We have equation of the type
109 * \f[
110 * {\bf X} {\bf A} + {\bf A} {\bf X} = {\bf B}
111 * \f]
112 * which is a symmetric Sylvester equation. To solve it we SVD the \f$ {\bf A} \f$ matrix
113 * (which is \f$ {\bf O}^{1/2} \f$):
114 * \f[
115 * {\bf A} = {\bf U}{\bf \Lambda}^{1/2} {\bf U}^{H}
116 * \f]
117 * Here \f$ \Lambda_i \f$ and \f$ {\bf U} \f$ are the eigen-values and eigen-vectors of the overap matrix
118 * \f$ {\bf O} \f$. Now we put it back to the original equation:
119 * \f[
120 * {\bf X} {\bf U}{\bf \Lambda}^{1/2} {\bf U}^{H} + {\bf U}{\bf \Lambda}^{1/2} {\bf U}^{H}{\bf X} = {\bf B}
121 * \f]
122 * Now we multiply with \f$ {\bf U}^{H} \f$ from the left and with \f$ {\bf U}\f$ from the right and
123 * simplify the right-hand side:
124 * \f[
125 * {\bf U}^{H} {\bf X} {\bf U}{\bf \Lambda}^{1/2} + {\bf \Lambda}^{1/2} {\bf U}^{H} {\bf X} {\bf U} =
126 * {\bf U}^{H} {\bf B} {\bf U} = -{\bf U}^{H} \Big( {\bf U}{\bf \Lambda}^{-1/2} {\bf U}^{H} \Big)
127 * {\bf O}' \Big( {\bf U}{\bf \Lambda}^{-1/2} {\bf U}^{H}\Big) {\bf U} =
128 * -{\bf \Lambda}^{-1/2} {\bf U}^{H} {\bf O}' {\bf U}{\bf \Lambda}^{-1/2}
129 * \f]
130 * or in the new basis
131 * \f[
132 * \tilde{\bf X} {\bf \Lambda}^{1/2} + {\bf \Lambda}^{1/2} \tilde{\bf X} = \tilde {\bf B}
133 * \f]
134 * Because \f$ {\bf \Lambda}^{1/2} \f$ is a diagonal matrix, we can write the last equation for each
135 * element of the matrix \f$ \tilde{\bf X} \f$:
136 * \f[
137 * \tilde X_{ij} \Lambda_{j}^{1/2} + \Lambda_{i}^{1/2} \tilde X_{ij} = \tilde B_{ij}
138 * \f]
139 * And thus
140 * \f[
141 * \tilde X_{ij} = \frac{\tilde B_{ij}}{\Lambda_{i}^{1/2} + \Lambda_{j}^{1/2}}
142 * \f]
143 *
144 * The elements of matrix \f$ \tilde {\bf B} \f$ have the following expression:
145 * \f[
146 * \tilde B_{ij} = -\Lambda_{i}^{-1/2} \tilde O_{ij}' \Lambda_{j}^{-1/2}
147 * \f]
148 * where
149 * \f[
150 * \tilde {\bf O'} = {\bf U}^{H} {\bf O}' {\bf U}
151 * \f]
152 *
153 * Putting all together, we can write the final expression for \f$ {\bf X} \f$:
154 * \f[
155 * {\bf X} = -{\bf U} \frac{\Lambda_{i}^{-1/2} ({\bf U}^{H}{\bf O}'{\bf U})_{ij} \Lambda_{j}^{-1/2} }
156 * {\Lambda_{i}^{1/2} + \Lambda_{j}^{1/2}} {\bf U}^{H}
157 *
158 * \f]
159 *
160 * Now we can draft the calculation of \f$ \frac{\partial}{\partial {\bf r}_{\alpha}} {\bf O}^{-1/2} \f$:
161 * - SVD the overlap matrix \f$ {\bf O} \f$
162 * - compute the derivative of \f$ {\bf O} \f$ for each atom displacement
163 * - compute \f$ \tilde {\bf O'} = {\bf U}^{H} {\bf O}' {\bf U} \f$
164 * - compute \f$ \tilde X_{ij} = \frac{\Lambda_{i}^{-1/2} \tilde O_{ij}' \Lambda_{j}^{-1/2}} {\Lambda_{i}^{1/2} + \Lambda_{j}^{1/2}} \f$
165 * - compute \f$ \frac{\partial}{\partial {\bf r}_{\alpha}} {\bf O}^{-1/2} = -{\bf U}\tilde {\bf X}{\bf U}^{H} \f$
166 */
168 sddk::mdarray<std::complex<double>, 5>& dn__);
169
170 /// Compute derivatives of the occupancy matrix w.r.t.atomic displacement.
171 /** \param [in] kp K-point.
172 * \param [in] q_op Overlap operator.
173 * \param [out] dn Derivative of the occupation number compared to displacement of each atom.
174 */
176 sddk::mdarray<std::complex<double>, 4>& dn__);
177
178 void set_hubbard_U_plus_V()
179 {
180 hubbard_U_plus_V_ = true;
181 }
182
183 inline int num_hubbard_wf() const
184 {
185 return ctx_.unit_cell().num_hubbard_wf().first;
186 }
187};
188
189} // namespace sirius
190
191#endif // __HUBBARD_HPP__
Contains declaration and implementation of sirius::Beta_projectors class.
Contains declaration and implementation of sirius::Beta_projectors_gradient class.
Contains declaration and implementation of sirius::Beta_projectors_strain_deriv class.
Apply Hubbard correction in the collinear case.
Definition: hubbard.hpp:50
bool hubbard_U_plus_V_
Hubbard correction with next nearest neighbors.
Definition: hubbard.hpp:57
void compute_occupancies_stress_derivatives(K_point< double > &kp__, Q_operator< double > &q_op__, sddk::mdarray< std::complex< double >, 4 > &dn__)
Compute derivatives of the occupancy matrix w.r.t.atomic displacement.
void compute_occupancies_derivatives(K_point< double > &kp__, Q_operator< double > &q_op__, sddk::mdarray< std::complex< double >, 5 > &dn__)
Compute the occupancy derivatives with respect to atomic displacements.
bool multi_channels_
Hubbard with multi channels apply to both LDA+U+V case.
Definition: hubbard.hpp:60
Hubbard(Simulation_context &ctx__)
Constructor.
Definition: hubbard.cpp:5
Simulation context is a set of parameters and objects describing a single simulation.
Representation of a unit cell.
Definition: unit_cell.hpp:43
Multidimensional array with the column-major (Fortran) order.
Definition: memory.hpp:660
Base class for Hubbard occupancy and potential matrices.
Contains definition of sirius::K_point class.
Contains declaration and partial implementation of sirius::K_point_set class.
Namespace of the SIRIUS library.
Definition: sirius.f90:5
Contains declaration of sirius::Non_local_operator class.
Representation of various radial integrals.
Contains definition and implementation of Simulation_context class.
Contains declaration and implementation of Wave_functions class.