SIRIUS 7.5.0
Electronic structure library and applications
|
Apply Hubbard correction in the collinear case. More...
#include <hubbard.hpp>
Public Member Functions | |
Hubbard (Simulation_context &ctx__) | |
Constructor. More... | |
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. More... | |
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. More... | |
void | set_hubbard_U_plus_V () |
int | num_hubbard_wf () const |
Private Member Functions | |
void | calculate_wavefunction_with_U_offset () |
Private Attributes | |
Simulation_context & | ctx_ |
Unit_cell & | unit_cell_ |
bool | hubbard_U_plus_V_ {false} |
Hubbard correction with next nearest neighbors. More... | |
bool | multi_channels_ {false} |
Hubbard with multi channels apply to both LDA+U+V case. More... | |
Apply Hubbard correction in the collinear case.
Definition at line 49 of file hubbard.hpp.
sirius::Hubbard::Hubbard | ( | Simulation_context & | ctx__ | ) |
Constructor.
Definition at line 5 of file hubbard.cpp.
void sirius::Hubbard::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.
To compute the occupancy derivatives, we first need to compute the derivatives of the matrix elements
\[ \frac{\partial}{\partial {\bf r}_{\alpha}} \langle \phi_{i}^{Hub} | S | \psi_{j{\bf k}} \rangle \]
Let's first derive the case of non-orthogonalized Hubbard atomic orbitals. In this case
\[ \frac{\partial}{\partial {\bf r}_{\alpha}} \langle \phi_{i}^{Hub} | S | \psi_{j{\bf k}} \rangle = \langle \frac{\partial}{\partial {\bf r}_{\alpha}} \phi_{i}^{Hub} | S | \psi_{j{\bf k}} \rangle + \langle \phi_{i}^{Hub} | \frac{\partial}{\partial {\bf r}_{\alpha}} S | \psi_{j{\bf k}} \rangle \]
Derivative \( \frac{\partial \phi_{i}}{\partial {\bf r}_{\alpha}} \) of the atomic functions is simple. For the wave-function of atom \( \alpha \) this is a multiplication of the plane-wave coefficients by \( {\bf G+k} \). For the rest of the atoms it is zero.
Derivative of the S-operator has the following expression:
\[ \frac{\partial}{\partial {\bf r}_{\alpha}} S = \sum_{\xi \xi'} |\frac{\partial}{\partial {\bf r}_{\alpha}} \beta_{\xi}^{\alpha} \rangle Q_{\xi \xi'}^{\alpha} \langle \beta_{\xi'}^{\alpha} | + |\beta_{\xi}^{\alpha}\rangle Q_{\xi \xi'}^{\alpha} \langle \frac{\partial}{\partial {\bf r}_{\alpha}} \beta_{\xi'}^{\alpha} | \]
Derivative of the inverse square root of the overlap matrix.
Let's label \( \frac{\partial}{\partial {\bf r}_{\alpha}} {\bf O}^{-1/2} = {\bf X} \). From taking derivative of the identity
\[ {\bf O}^{-1/2} {\bf O} {\bf O}^{-1/2}= {\bf I} \]
we get
\[ {\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 \]
or simplifying
\[ {\bf X} {\bf O}^{1/2} + {\bf O}^{1/2}{\bf X} = -{\bf O}^{-1/2}{\bf O}'{\bf O}^{-1/2} \]
We have equation of the type
\[ {\bf X} {\bf A} + {\bf A} {\bf X} = {\bf B} \]
which is a symmetric Sylvester equation. To solve it we SVD the \( {\bf A} \) matrix (which is \( {\bf O}^{1/2} \)):
\[ {\bf A} = {\bf U}{\bf \Lambda}^{1/2} {\bf U}^{H} \]
Here \( \Lambda_i \) and \( {\bf U} \) are the eigen-values and eigen-vectors of the overap matrix \( {\bf O} \). Now we put it back to the original equation:
\[ {\bf X} {\bf U}{\bf \Lambda}^{1/2} {\bf U}^{H} + {\bf U}{\bf \Lambda}^{1/2} {\bf U}^{H}{\bf X} = {\bf B} \]
Now we multiply with \( {\bf U}^{H} \) from the left and with \( {\bf U}\) from the right and simplify the right-hand side:
\[ {\bf U}^{H} {\bf X} {\bf U}{\bf \Lambda}^{1/2} + {\bf \Lambda}^{1/2} {\bf U}^{H} {\bf X} {\bf U} = {\bf U}^{H} {\bf B} {\bf U} = -{\bf U}^{H} \Big( {\bf U}{\bf \Lambda}^{-1/2} {\bf U}^{H} \Big) {\bf O}' \Big( {\bf U}{\bf \Lambda}^{-1/2} {\bf U}^{H}\Big) {\bf U} = -{\bf \Lambda}^{-1/2} {\bf U}^{H} {\bf O}' {\bf U}{\bf \Lambda}^{-1/2} \]
or in the new basis
\[ \tilde{\bf X} {\bf \Lambda}^{1/2} + {\bf \Lambda}^{1/2} \tilde{\bf X} = \tilde {\bf B} \]
Because \( {\bf \Lambda}^{1/2} \) is a diagonal matrix, we can write the last equation for each element of the matrix \( \tilde{\bf X} \):
\[ \tilde X_{ij} \Lambda_{j}^{1/2} + \Lambda_{i}^{1/2} \tilde X_{ij} = \tilde B_{ij} \]
And thus
\[ \tilde X_{ij} = \frac{\tilde B_{ij}}{\Lambda_{i}^{1/2} + \Lambda_{j}^{1/2}} \]
The elements of matrix \( \tilde {\bf B} \) have the following expression:
\[ \tilde B_{ij} = -\Lambda_{i}^{-1/2} \tilde O_{ij}' \Lambda_{j}^{-1/2} \]
where
\[ \tilde {\bf O'} = {\bf U}^{H} {\bf O}' {\bf U} \]
Putting all together, we can write the final expression for \( {\bf X} \):
\[ {\bf X} = -{\bf U} \frac{\Lambda_{i}^{-1/2} ({\bf U}^{H}{\bf O}'{\bf U})_{ij} \Lambda_{j}^{-1/2} } {\Lambda_{i}^{1/2} + \Lambda_{j}^{1/2}} {\bf U}^{H} \]
Now we can draft the calculation of \( \frac{\partial}{\partial {\bf r}_{\alpha}} {\bf O}^{-1/2} \):
Definition at line 128 of file hubbard_occupancies_derivatives.cpp.
void sirius::Hubbard::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.
[in] | kp | K-point. |
[in] | q_op | Overlap operator. |
[out] | dn | Derivative of the occupation number compared to displacement of each atom. |
Definition at line 377 of file hubbard_occupancies_derivatives.cpp.
|
inline |
Definition at line 178 of file hubbard.hpp.
|
inline |
Definition at line 183 of file hubbard.hpp.
|
private |
Definition at line 52 of file hubbard.hpp.
|
private |
Definition at line 54 of file hubbard.hpp.
|
private |
Hubbard correction with next nearest neighbors.
Definition at line 57 of file hubbard.hpp.
|
private |
Hubbard with multi channels apply to both LDA+U+V case.
Definition at line 60 of file hubbard.hpp.