30Hubbard_matrix::Hubbard_matrix(Simulation_context& ctx__)
33 if (!ctx_.full_potential() && ctx_.hubbard_correction()) {
36 int num_atomic_level{0};
37 atomic_orbitals_.clear();
38 for (
int ia = 0; ia < ctx_.unit_cell().num_atoms(); ia++) {
39 auto& atom_type = ctx_.unit_cell().atom(ia).type();
40 if (atom_type.hubbard_correction()) {
41 num_atomic_level += atom_type.lo_descriptor_hub().size();
43 for (
int lo = 0; lo < static_cast<int>(atom_type.lo_descriptor_hub().size()); lo++) {
44 atomic_orbitals_.push_back(std::make_pair(ia, lo));
49 local_ = std::vector<sddk::mdarray<std::complex<double>, 3>>(num_atomic_level);
58 offset_ = std::vector<int>(num_atomic_level, 0);
61 for (
int at_lvl = 0; at_lvl < static_cast<int>(local_.size()); at_lvl++) {
62 offset_[at_lvl] = size;
63 int ia = atomic_orbitals_[at_lvl].first;
64 auto& atom_type = ctx_.unit_cell().atom(ia).type();
65 int lo_ind = atomic_orbitals_[at_lvl].second;
66 int l = atom_type.lo_descriptor_hub(lo_ind).l();
69 local_[at_lvl] = sddk::mdarray<std::complex<double>, 3>(mmax, mmax, 4, sddk::memory_t::host,
"local_hubbard");
70 local_[at_lvl].zero();
75 nonlocal_ = std::vector<sddk::mdarray<std::complex<double>, 3>>(ctx_.cfg().hubbard().nonlocal().size());
76 for (
int i = 0; i < static_cast<int>(ctx_.cfg().hubbard().nonlocal().size()); i++) {
77 auto nl = ctx_.cfg().hubbard().nonlocal(i);
80 nonlocal_[i] = sddk::mdarray<std::complex<double>, 3>(2 * il + 1, 2 * jl + 1, ctx_.num_spins(),
81 sddk::memory_t::host,
"nonlocal_hubbard");
88Hubbard_matrix::access(std::string
const& what__, std::complex<double>* occ__,
int ld__)
90 if (!(what__ ==
"get" || what__ ==
"set")) {
92 s <<
"wrong access label: " << what__;
98 if (ctx_.num_mag_dims() == 3) {
103 if (what__ ==
"get") {
107 for (
int at_lvl = 0; at_lvl < static_cast<int>(
local().size()); at_lvl++) {
108 const int ia1 = atomic_orbitals(at_lvl).first;
109 const auto& atom = ctx_.unit_cell().atom(ia1);
110 const int lo = atomic_orbitals(at_lvl).second;
111 if (atom.type().lo_descriptor_hub(lo).use_for_calculation()) {
112 const int l = atom.type().lo_descriptor_hub(lo).l();
113 const int offset = offset_[at_lvl];
114 for (
int m1 = -l; m1 <= l; m1++) {
115 for (
int m2 = -l; m2 <= l; m2++) {
116 if (what__ ==
"get") {
117 for (
int j = 0; j < ((ctx_.num_mag_dims() == 3) ? 4 : ctx_.num_spins()); j++) {
118 occ_mtrx(offset + l + m1, offset + l + m2, j, ia1) = this->
local(at_lvl)(l + m1, l + m2, j);
121 for (
int j = 0; j < ((ctx_.num_mag_dims() == 3) ? 4 : ctx_.num_spins()); j++) {
122 this->
local(at_lvl)(l + m1, l + m2, j) = occ_mtrx(offset + l + m1, offset + l + m2, j, ia1);
132Hubbard_matrix::print_local(
int at_lvl__, std::ostream& out__)
const
137 auto print_number = [&](
double x) { out__ << std::setw(width) << std::setprecision(prec) << std::fixed << x; };
138 auto const& atom = ctx_.unit_cell().atom(atomic_orbitals_[at_lvl__].first);
140 out__ <<
"level : " << atom.type().lo_descriptor_hub(atomic_orbitals_[at_lvl__].second).n();
141 out__ <<
" l: " << atom.type().lo_descriptor_hub(atomic_orbitals_[at_lvl__].second).l() << std::endl;
142 const int l = atom.type().lo_descriptor_hub(atomic_orbitals_[at_lvl__].second).l();
143 if (ctx_.num_mag_dims() != 3) {
144 int mmax = 2 * l + 1;
145 for (
int is = 0; is < ctx_.num_spins(); is++) {
146 out__ << hbar(width * mmax,
'-') << std::endl;
147 bool has_imag{
false};
148 for (
int m = 0; m < mmax; m++) {
149 for (
int mp = 0; mp < mmax; mp++) {
150 if (std::abs(std::imag(this->
local(at_lvl__)(m, mp, is))) > 1e-12) {
153 print_number(std::real(this->
local(at_lvl__)(m, mp, is)));
158 out__ <<
"imaginary part:" << std::endl;
159 for (
int m = 0; m < mmax; m++) {
160 for (
int mp = 0; mp < mmax; mp++) {
161 print_number(std::imag(this->
local(at_lvl__)(m, mp, is)));
167 out__ << hbar(width * mmax,
'-') << std::endl;
169 int mmax = 2 * l + 1;
170 out__ << hbar(2 * width * mmax + 3,
'-') << std::endl;
171 for (
int m = 0; m < mmax; m++) {
172 for (
int mp = 0; mp < mmax; mp++) {
173 print_number(std::real(this->
local(at_lvl__)(m, mp, 0)));
176 for (
int mp = 0; mp < mmax; mp++) {
177 print_number(std::real(this->
local(at_lvl__)(m, mp, 2)));
181 out__ << hbar(2 * width * mmax + 3,
'-') << std::endl;
182 for (
int m = 0; m < mmax; m++) {
183 for (
int mp = 0; mp < mmax; mp++) {
184 print_number(std::real(this->
local(at_lvl__)(m, mp, 3)));
187 for (
int mp = 0; mp < mmax; mp++) {
188 print_number(std::real(this->
local(at_lvl__)(m, mp, 1)));
192 out__ << hbar(2 * width * mmax + 3,
'-') << std::endl;
197Hubbard_matrix::print_nonlocal(
int idx__, std::ostream& out__)
const
200 auto nl = ctx_.cfg().hubbard().nonlocal(idx__);
201 int ia = nl.atom_pair()[0];
202 int ja = nl.atom_pair()[1];
205 const int jb = 2 * jl + 1;
206 const int ib = 2 * il + 1;
207 r3::vector<int> T(nl.T());
209 r3::vector<double> r = ctx_.unit_cell().atom(ja).position() + T - ctx_.unit_cell().atom(ia).position();
211 auto rc = dot(ctx_.unit_cell().lattice_vectors(), r);
213 out__ <<
"atom: " << ia <<
", l: " << il <<
" -> atom: " << ja <<
", l: " << jl <<
", T: " << T
214 <<
", r: " << rc << std::endl;
218 auto print_number = [&](
double x) { out__ << std::setw(width) << std::setprecision(prec) << std::fixed << x; };
220 if (ctx_.num_mag_dims() != 3) {
221 for (
int is = 0; is < ctx_.num_spins(); is++) {
222 out__ << hbar(width * jb,
'-') << std::endl;
223 bool has_imag{
false};
224 for (
int m = 0; m < ib; m++) {
225 for (
int mp = 0; mp < jb; mp++) {
226 if (std::abs(std::imag(this->nonlocal(idx__)(m, mp, is))) > 1e-12) {
229 print_number(std::real(this->nonlocal(idx__)(m, mp, is)));
234 out__ <<
"imaginary part:" << std::endl;
235 for (
int m = 0; m < ib; m++) {
236 for (
int mp = 0; mp < jb; mp++) {
237 print_number(std::imag(this->nonlocal(idx__)(m, mp, is)));
243 out__ << hbar(width * jb,
'-') << std::endl;
277 for (
int ia = 0; ia < static_cast<int>(local_.size()); ia++) {
281 for (
int i = 0; i < static_cast<int>(ctx_.cfg().hubbard().nonlocal().size()); i++) {
Multidimensional array with the column-major (Fortran) order.
void zero(memory_t mem__, size_t idx0__, size_t n__)
Zero n elements starting from idx0.
Base class for Hubbard occupancy and potential matrices.
void zero(T *ptr__, size_t n__)
Zero the device memory.
Namespace of the SIRIUS library.