25#ifndef __HUBBARD_ORBITALS_DESCRIPTOR_HPP__
26#define __HUBBARD_ORBITALS_DESCRIPTOR_HPP__
71 std::vector<double> initial_occupancy_;
76 inline auto hubbard_F_coefficients()
const
78 std::vector<double> F(4);
91 F[1] = 5.0 * J() + 31.5 * B();
92 F[2] = 9.0 * J() - 31.5 * B();
96 F[1] = (225.0 / 54.0) * J() + (32175.0 / 42.0) * E2() + (2475.0 / 42.0) * E3();
97 F[2] = 11.0 * J() - (141570.0 / 77.0) * E2() + (4356.0 / 77.0) * E3();
98 F[3] = (7361.640 / 594.0) * J() + (36808.20 / 66.0) * E2() - 111.54 * E3();
103 s <<
"Hubbard correction not implemented for l > 3\n"
104 <<
" current l: " << this->l();
112 inline void calculate_ak_coefficients(sddk::mdarray<double, 5>& ak)
126 for (
int m1 = -l; m1 <= l; m1++) {
127 for (
int m2 = -l; m2 <= l; m2++) {
128 for (
int m3 = -l; m3 <= l; m3++) {
129 for (
int m4 = -l; m4 <= l; m4++) {
130 for (
int k = 0; k < 2 * l; k += 2) {
132 for (
int q = -k; q <= k; q++) {
138 ak(k / 2, m1 + l, m2 + l, m3 + l, m4 + l) = 4.0 * sum *
pi /
static_cast<double>(2 * k + 1);
158 auto F = hubbard_F_coefficients();
159 calculate_ak_coefficients(ak);
164 this->hubbard_matrix_.
zero();
165 for (
int m1 = 0; m1 < 2 * l + 1; m1++) {
166 for (
int m2 = 0; m2 < 2 * l + 1; m2++) {
167 for (
int m3 = 0; m3 < 2 * l + 1; m3++) {
168 for (
int m4 = 0; m4 < 2 * l + 1; m4++) {
169 for (
int k = 0; k < l; k++) {
170 this->hubbard_matrix(m1, m2, m3, m4) += ak(k, m1, m3, m2, m4) * F[k];
178 void initialize_hubbard_matrix()
182 auto F = hubbard_F_coefficients();
183 calculate_ak_coefficients(ak);
189 this->hubbard_matrix_.
zero();
190 for (
int m1 = 0; m1 < 2 * l + 1; m1++) {
191 for (
int m2 = 0; m2 < 2 * l + 1; m2++) {
192 for (
int m3 = 0; m3 < 2 * l + 1; m3++) {
193 for (
int m4 = 0; m4 < 2 * l + 1; m4++) {
194 for (
int k = 0; k < l; k++) {
195 this->hubbard_matrix(m1, m2, m3, m4) += ak(k, m1, m3, m2, m4) * F[k];
212 const double J__,
const double U__,
const double* hub_coef__,
const double alpha__,
213 const double beta__,
const double J0__, std::vector<double> initial_occupancy__,
225 , initial_occupancy_(initial_occupancy__)
229 for (
int s = 0; s < 4; s++) {
233 initialize_hubbard_matrix();
252 , initial_occupancy_(src.initial_occupancy_)
255 hubbard_matrix_ = std::move(src.hubbard_matrix_);
256 for (
int s = 0; s < 4; s++) {
259 f_ = std::move(src.f_);
272 inline double hubbard_matrix(
const int m1,
const int m2,
const int m3,
const int m4)
const
274 return hubbard_matrix_(m1, m2, m3, m4);
277 inline double& hubbard_matrix(
const int m1,
const int m2,
const int m3,
const int m4)
279 return hubbard_matrix_(m1, m2, m3, m4);
282 inline double J0()
const
287 inline double U()
const
292 inline double J()
const
297 inline double U_minus_J()
const
299 return this->U() - this->J();
302 inline double B()
const
307 inline double E2()
const
312 inline double E3()
const
317 inline double alpha()
const
322 inline double beta()
const
327 inline double occupancy()
const
332 Spline<double>
const& f()
const
337 bool use_for_calculation()
const
342 auto const& initial_occupancy()
const
344 return initial_occupancy_;
353inline std::ostream&
operator<<(std::ostream& out, hubbard_orbital_descriptor
const& ho)
355 out <<
"{n: " << ho.n() <<
", l: " << ho.l() <<
"}";
static double gaunt_rlm_ylm_rlm(int l1, int l2, int l3, int m1, int m2, int m3)
Gaunt coefficent of two real spherical harmonics with a complex one.
Structure containing all information about a specific hubbard orbital (including the radial function)...
double J_
Hubbard J parameter (exchange).
std::array< double, 4 > hubbard_coefficients_
Different hubbard coefficients.
double occupancy_
Orbital occupancy.
int idx_wf_
Index of the corresponding atomic wave-function.
double U_
Hubbard U parameter (on-site repulsion).
hubbard_orbital_descriptor(const int n__, const int l__, const int orbital_index__, const double occ__, const double J__, const double U__, const double *hub_coef__, const double alpha__, const double beta__, const double J0__, std::vector< double > initial_occupancy__, Spline< double > f__, bool use_for_calculations__, int idx_wf__)
Constructor.
hubbard_orbital_descriptor()
Constructor.
int n_
Principal quantum number of atomic orbital.
int l_
Orbital quantum number of atomic orbital.
bool use_for_calculation_
Set to true if this orbital is part the Hubbard subspace.
void compute_hubbard_matrix()
hubbard_orbital_descriptor(hubbard_orbital_descriptor &&src)
Move constructor.
void zero(memory_t mem__, size_t idx0__, size_t n__)
Zero n elements starting from idx0.
Namespace of the SIRIUS library.
std::ostream & operator<<(std::ostream &out, hbar &&b)
Inject horisontal bar to ostream.
Contains declaration and particular implementation of sirius::SHT class.