SIRIUS 7.5.0
Electronic structure library and applications
Public Member Functions | Private Member Functions | Private Attributes | List of all members
sirius::Hubbard Class Reference

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_contextctx_
 
Unit_cellunit_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...
 

Detailed Description

Apply Hubbard correction in the collinear case.

Definition at line 49 of file hubbard.hpp.

Constructor & Destructor Documentation

◆ Hubbard()

sirius::Hubbard::Hubbard ( Simulation_context ctx__)

Constructor.

Definition at line 5 of file hubbard.cpp.

Member Function Documentation

◆ compute_occupancies_derivatives()

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} \):

  • SVD the overlap matrix \( {\bf O} \)
  • compute the derivative of \( {\bf O} \) for each atom displacement
  • compute \( \tilde {\bf O'} = {\bf U}^{H} {\bf O}' {\bf U} \)
  • compute \( \tilde X_{ij} = \frac{\Lambda_{i}^{-1/2} \tilde O_{ij}' \Lambda_{j}^{-1/2}} {\Lambda_{i}^{1/2} + \Lambda_{j}^{1/2}} \)
  • compute \( \frac{\partial}{\partial {\bf r}_{\alpha}} {\bf O}^{-1/2} = -{\bf U}\tilde {\bf X}{\bf U}^{H} \)

Definition at line 128 of file hubbard_occupancies_derivatives.cpp.

◆ compute_occupancies_stress_derivatives()

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.

Parameters
[in]kpK-point.
[in]q_opOverlap operator.
[out]dnDerivative of the occupation number compared to displacement of each atom.

Definition at line 377 of file hubbard_occupancies_derivatives.cpp.

◆ set_hubbard_U_plus_V()

void sirius::Hubbard::set_hubbard_U_plus_V ( )
inline

Definition at line 178 of file hubbard.hpp.

◆ num_hubbard_wf()

int sirius::Hubbard::num_hubbard_wf ( ) const
inline

Definition at line 183 of file hubbard.hpp.

Member Data Documentation

◆ ctx_

Simulation_context& sirius::Hubbard::ctx_
private

Definition at line 52 of file hubbard.hpp.

◆ unit_cell_

Unit_cell& sirius::Hubbard::unit_cell_
private

Definition at line 54 of file hubbard.hpp.

◆ hubbard_U_plus_V_

bool sirius::Hubbard::hubbard_U_plus_V_ {false}
private

Hubbard correction with next nearest neighbors.

Definition at line 57 of file hubbard.hpp.

◆ multi_channels_

bool sirius::Hubbard::multi_channels_ {false}
private

Hubbard with multi channels apply to both LDA+U+V case.

Definition at line 60 of file hubbard.hpp.


The documentation for this class was generated from the following files: