SIRIUS 7.5.0
Electronic structure library and applications
occupation_matrix.hpp
Go to the documentation of this file.
1// Copyright (c) 2013-2020 Mathieu Taillefumier, Mthieu 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 occupation_matrix.hpp
21 *
22 * \brief Occupation matrix of the LDA+U method.
23 */
24
25#ifndef __OCCUPATION_MATRIX_HPP__
26#define __OCCUPATION_MATRIX_HPP__
27
28#include "SDDK/memory.hpp"
29#include "k_point/k_point.hpp"
31
32namespace sirius {
33
35{
36 private:
37 /// K-point contribution to density matrices weighted with e^{ikT} phase factors.
38 std::map<r3::vector<int>, sddk::mdarray<std::complex<double>, 3>> occ_mtrx_T_;
39
40 public:
42
43 template <typename T>
44 void add_k_point_contribution(K_point<T>& kp__);
45
46 /** The initial occupancy is calculated following Hund rules. We first
47 * fill the d (f) states according to the hund's rules and with majority
48 * spin first and the remaining electrons distributed among the minority states. */
49 void init();
50
51 void reduce()
52 {
53 if (!ctx_.hubbard_correction()) {
54 return;
55 }
56
57 /* global reduction over k points */
58 for (int at_lvl = 0; at_lvl < (int)this->local_.size(); at_lvl++) {
59 const int ia = atomic_orbitals_[at_lvl].first;
60 auto const& atom = ctx_.unit_cell().atom(ia);
61 if (atom.type().lo_descriptor_hub(atomic_orbitals_[at_lvl].second).use_for_calculation()) {
62 ctx_.comm_k().allreduce(this->local(at_lvl).at(sddk::memory_t::host),
63 static_cast<int>(this->local(at_lvl).size()));
64 }
65 }
66
67 /* reduce occ_mtrx_T_ (not nonlocal - it is computed during symmetrization from occ_mtrx_T_) */
68 for (auto& e : this->occ_mtrx_T_) {
69 ctx_.comm_k().allreduce(e.second.at(sddk::memory_t::host), static_cast<int>(e.second.size()));
70 }
71 }
72
73 void update_nonlocal()
74 {
75 if (ctx_.num_mag_dims() == 3) {
76 RTE_THROW("only collinear case is supported");
77 }
78 for (int i = 0; i < static_cast<int>(ctx_.cfg().hubbard().nonlocal().size()); i++) {
79 auto nl = ctx_.cfg().hubbard().nonlocal(i);
80 int ia = nl.atom_pair()[0];
81 int ja = nl.atom_pair()[1];
82 int il = nl.l()[0];
83 int jl = nl.l()[1];
84 int n1 = nl.n()[0];
85 int n2 = nl.n()[1];
86 int ib = 2 * il + 1;
87 int jb = 2 * jl + 1;
88 auto T = nl.T();
89 this->nonlocal(i).zero();
90
91 /* NOTE : the atom order is important here. */
92 int at1_lvl = this->find_orbital_index(ia, n1, il);
93 int at2_lvl = this->find_orbital_index(ja, n2, jl);
94 auto const& occ_mtrx = occ_mtrx_T_.at(T);
95
96 for (int ispn = 0; ispn < ctx_.num_spins(); ispn++) {
97 for (int m1 = 0; m1 < ib; m1++) {
98 for (int m2 = 0; m2 < jb; m2++) {
99 this->nonlocal(i)(m1, m2, ispn) = occ_mtrx(this->offset(at1_lvl) + m1, this->offset(at2_lvl) + m2, ispn);
100 }
101 }
102 }
103 }
104 }
105
106 void zero()
107 {
108 Hubbard_matrix::zero();
109 for (auto& e : occ_mtrx_T_) {
110 e.second.zero();
111 }
112 }
113
114 void print_occupancies(int verbosity__) const;
115
116 inline auto const& occ_mtrx_T(r3::vector<int> T__) const
117 {
118 return occ_mtrx_T_.at(T__);
119 }
120
121 inline auto const& occ_mtrx_T() const
122 {
123 return occ_mtrx_T_;
124 }
125
126 friend void
127 copy(Occupation_matrix const& src__, Occupation_matrix& dest__);
128};
129
130inline void
131copy(Occupation_matrix const& src__, Occupation_matrix& dest__)
132{
133 for (int at_lvl = 0; at_lvl < static_cast<int>(src__.atomic_orbitals().size()); at_lvl++) {
134 sddk::copy(src__.local(at_lvl), dest__.local(at_lvl));
135 }
136 for (int i = 0; i < static_cast<int>(src__.ctx().cfg().hubbard().nonlocal().size()); i++) {
137 sddk::copy(src__.nonlocal(i), dest__.nonlocal(i));
138 }
139 for (auto& e : src__.occ_mtrx_T()) {
140 sddk::copy(e.second, dest__.occ_mtrx_T_.at(e.first));
141 }
142}
143
144} // namespace sirius
145#endif
Describes Hubbard orbital occupancy or potential correction matrices.
std::vector< sddk::mdarray< std::complex< double >, 3 > > local_
Local part of Hubbard matrix.
auto & local() const
Return a vector containing the occupation numbers for each atomic orbital.
K-point related variables and methods.
Definition: k_point.hpp:44
std::map< r3::vector< int >, sddk::mdarray< std::complex< double >, 3 > > occ_mtrx_T_
K-point contribution to density matrices weighted with e^{ikT} phase factors.
Simulation context is a set of parameters and objects describing a single simulation.
auto const & comm_k() const
Communicator between k-points.
int num_spins() const
Number of spin components.
int num_mag_dims() const
Number of dimensions in the magnetization vector.
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.
Memory management functions and classes.
void copy(T *target__, T const *source__, size_t n__)
Copy memory inside a device.
Definition: acc.hpp:320
Namespace of the SIRIUS library.
Definition: sirius.f90:5