SIRIUS 7.5.0
Electronic structure library and applications
symmetrize_density_matrix.hpp
Go to the documentation of this file.
1// Copyright (c) 2013-2023 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 symmetrize_density_matrix.hpp
21 *
22 * \brief Symmetrize density matrix of LAPW and PW methods.
23 */
24
25#ifndef __SYMMETRIZE_DENSITY_MATRIX_HPP__
26#define __SYMMETRIZE_DENSITY_MATRIX_HPP__
27
28#include "density/density_matrix.hpp"
29
30namespace sirius {
31
32inline void
33apply_symmetry_to_density_matrix(sddk::mdarray<std::complex<double>, 3> const& dm_ia__,
34 basis_functions_index const& indexb__, const int num_mag_comp__,
35 std::vector<sddk::mdarray<double, 2>> const& rotm__,
36 sddk::mdarray<std::complex<double>, 2> const& spin_rot_su2__,
37 sddk::mdarray<std::complex<double>, 3>& dm_ja__)
38{
39 auto& indexr = indexb__.indexr();
40
41 /* loop over radial functions */
42 for (auto e1 : indexr) {
43 /* angular momentum of radial function */
44 auto am1 = e1.am;
45 auto ss1 = am1.subshell_size();
46 auto offset1 = indexb__.index_of(e1.idxrf);
47 for (auto e2 : indexr) {
48 /* angular momentum of radial function */
49 auto am2 = e2.am;
50 auto ss2 = am2.subshell_size();
51 auto offset2 = indexb__.index_of(e2.idxrf);
52
53 /* apply spatial rotation */
54 for (int m1 = 0; m1 < ss1; m1++) {
55 for (int m2 = 0; m2 < ss2; m2++) {
56 std::array<std::complex<double>, 3> dm_rot_spatial = {0, 0, 0};
57 for (int j = 0; j < num_mag_comp__; j++) {
58 for (int m1p = 0; m1p < ss1; m1p++) {
59 for (int m2p = 0; m2p < ss2; m2p++) {
60 dm_rot_spatial[j] += rotm__[am1.l()](m1, m1p) *
61 dm_ia__(offset1 + m1p, offset2 + m2p, j) *
62 rotm__[am2.l()](m2, m2p);
63 }
64 }
65 }
66 /* non-magnetic case */
67 if (num_mag_comp__ == 1) {
68 dm_ja__(offset1 + m1, offset2 + m2, 0) += dm_rot_spatial[0];
69 } else { /* magnetic symmetrization */
70 std::complex<double> spin_dm[2][2] = {{dm_rot_spatial[0], dm_rot_spatial[2]},
71 {std::conj(dm_rot_spatial[2]), dm_rot_spatial[1]}};
72
73 /* spin blocks of density matrix are: uu, dd, ud
74 the mapping from linear index (0, 1, 2) of density matrix components is:
75 for the first spin index: k & 1, i.e. (0, 1, 2) -> (0, 1, 0)
76 for the second spin index: min(k, 1), i.e. (0, 1, 2) -> (0, 1, 1)
77 */
78 for (int k = 0; k < num_mag_comp__; k++) {
79 for (int is = 0; is < 2; is++) {
80 for (int js = 0; js < 2; js++) {
81 dm_ja__(offset1 + m1, offset2 + m2, k) +=
82 spin_rot_su2__(k & 1, is) * spin_dm[is][js] *
83 std::conj(spin_rot_su2__(std::min(k, 1), js));
84 }
85 }
86 }
87 }
88 }
89 }
90 }
91 }
92}
93
94/// Symmetrize density matrix.
95/** Density matrix arises in LAPW or PW methods. In PW it is computed in the basis of beta-projectors. Occupancy
96 * matrix is computed for the Hubbard-U correction. In both cases the matrix has the same structure and is
97 * symmetrized in the same way The symmetrization does depend explicitly on the beta or wfc. The last
98 * parameter is on when the atom has spin-orbit coupling and hubbard correction in
99 * that case, we must skip half of the indices because of the averaging of the
100 * radial integrals over the total angular momentum
101 *
102 * We start from the spectral represntation of the occupancy operator defined for the irreducible Brillouin
103 * zone:
104 * \f[
105 * \hat N_{IBZ} = \sum_{j} \sum_{{\bf k}}^{IBZ} | \Psi_{j{\bf k}}^{\sigma} \rangle w_{\bf k} n_{j{\bf k}}
106 * \langle \Psi_{j{\bf k}}^{\sigma'} |
107 * \f]
108 * and a set of localized orbitals with the pure angular character (this can be LAPW functions,
109 * beta-projectors or localized Hubbard orbitals) :
110 * \f[
111 * |\phi_{\ell m}^{\alpha {\bf T}}\rangle
112 * \f]
113 * The orbitals are labeled by the angular and azimuthal quantum numbers (\f$ \ell m \f$),
114 * atom index (\f$ \alpha \f$) and a lattice translation vector (\f$ {\bf T} \f$) such that:
115 * \f[
116 * \langle {\bf r} | \phi_{\ell m}^{\alpha {\bf T}} \rangle = \phi_{\ell m}({\bf r - r_{\alpha} - T})
117 * \f]
118 *
119 * There might be several localized orbitals per atom. We wish to compute the symmetrized occupation matrix:
120 * \f[
121 * n_{\ell m \alpha {\bf T} \sigma, \ell' m' \alpha' {\bf T}' \sigma'} =
122 * \langle \phi_{\ell m}^{\alpha {\bf T}} | \hat N | \phi_{\ell' m'}^{\alpha' {\bf T'}} \rangle =
123 * \sum_{\bf P} \sum_{j} \sum_{{\bf k}}^{IBZ}
124 * \langle \phi_{\ell m}^{\alpha {\bf T}} | \hat{\bf P} \Psi_{j{\bf k}}^{\sigma} \rangle
125 * w_{\bf k} n_{j{\bf k}}
126 * \langle \hat{\bf P} \Psi_{j{\bf k}}^{\sigma'} | \phi_{\ell' m'}^{\alpha' {\bf T'}} \rangle
127 * \f]
128 *
129 * Let's now label the overlap integrals between localized orbitals and KS wave-functions:
130 * \f[
131 * A_{\ell m j{\bf k}}^{\alpha {\bf T} \sigma} = \langle \Psi_{j{\bf k}}^{\sigma} |
132 * \phi_{\ell m}^{\alpha {\bf T}} \rangle =
133 * \int \Psi_{j{\bf k}}^{\sigma *}({\bf r})
134 * \phi_{\ell m}({\bf r} - {\bf r}_{\alpha} - {\bf T}) d{\bf r}
135 * \f]
136 * and check how it transforms under the symmetry operation \f$ \hat {\bf P} = \{ {\bf R} | {\bf t} \} \f$
137 * applied to the KS states.
138 * \f[
139 * \int \big( \hat {\bf P}\Psi_{j {\bf k}}^{\sigma *}({\bf r}) \big)
140 * \phi_{\ell m}({\bf r} - {\bf r}_{\alpha} - {\bf T}) d{\bf r} =
141 * \int \Psi_{j {\bf k}}^{\sigma *}({\bf r})
142 * \big( \hat {\bf P}^{-1} \phi_{\ell m}({\bf r} - {\bf r}_{\alpha} - {\bf T}) \big) d{\bf r}
143 * \f]
144 *
145 * Let's first derive how the inverse symmetry operation acts on the localized orbital centered on the
146 * atom inside a unit cell (no <b>T</b>):
147 * \f[
148 * \hat {\bf P}^{-1} \phi\big( {\bf r} - {\bf r}_{\alpha} \big) =
149 * \phi\big( {\bf R} {\bf r} + {\bf t} - {\bf r}_{\alpha} \big) = \\
150 * \phi\big( {\bf R}({\bf r} - {\bf R}^{-1}({\bf r}_{\alpha} - {\bf t})) \big) =
151 * \tilde \phi \big( {\bf r} - {\bf R}^{-1}({\bf r}_{\alpha} - {\bf t}) \big)
152 * \f]
153 * This operation rotates the orbital and centers it at the position
154 * \f[
155 * {\bf r}_{\beta} = {\bf R}^{-1}{\bf r}_{\alpha} - {\bf R}^{-1}{\bf t} = \hat {\bf P}^{-1}{\bf r}_{\alpha}
156 * \f]
157 *
158 *
159 * For example, suppose thar we have y-orbital centered at \f$ {\bf r}_{\alpha} = [1, 0] \f$ (black dot)
160 * and a symmetry operation \f$ \hat {\bf P} = \{ {\bf R} | {\bf t} \} \f$ that rotates by
161 * \f$ \pi/2 \f$ counterclockwise and translates by [1/2, 1/2]:
162 *
163 * \image html sym_orbital1.png width=400px
164 *
165 * Under this symmetry operation the atom coordinate will transform into [1/2, 3/2] (red dot), but
166 * this is not(!) how the orbital is transformed. The origin of the atom will transform according to
167 * the inverse of \f$ \hat {\bf P} \f$ into \f$ {\bf r}_{\beta} = [-1/2, -1/2] \f$ (blue dot) such that
168 * \f$ \hat {\bf P} {\bf r}_{\beta} = {\bf r}_{\alpha} \f$:
169 *
170 * \image html sym_orbital2.png width=400px
171 *
172 * To be more precise, we should highlight that the transformed atom coordinate can go out of the original
173 * unit cell and can be brought back with a translation vector:
174 * \f[
175 * \hat {\bf P}^{-1}{\bf r}_{\alpha} = {\bf r}_{\beta} + {\bf T}_{P\alpha\beta}
176 * \f]
177 *
178 * Now let's derive how the inverse symmetry operation acts on the localized orbital \f$ \phi({\bf r}) \f$
179 * centered on atom in the arbitrary unit cell:
180 * \f[
181 * \hat {\bf P}^{-1} \phi\big( {\bf r} - {\bf r}_{\alpha} - {\bf T} \big) =
182 * \phi\big( {\bf R} {\bf r} + {\bf t} - {\bf r}_{\alpha} - {\bf T} \big) = \\
183 * \phi\big( {\bf R}({\bf r} - {\bf R}^{-1}({\bf r}_{\alpha} + {\bf T} - {\bf t})) \big) =
184 * \tilde \phi\big( {\bf r} - {\bf R}^{-1}({\bf r}_{\alpha} + {\bf T} - {\bf t}) \big) =
185 * \tilde \phi\big( {\bf r} - {\bf r}_{\beta} - {\bf T}_{P\alpha\beta} - {\bf R}^{-1}{\bf T} \big)
186 * \f]
187 *
188 * Now let's check how the atomic orbitals transfrom under the rotational part of the symmetry operation.
189 * The atomic functions of (\f$ \ell m \f$) character is expressed as a product of radial function and a
190 * spherical harmonic:
191 * \f[
192 * \phi_{\ell m}({\bf r}) = \phi_{\ell}(r) Y_{\ell m}(\theta, \phi)
193 * \f]
194 *
195 * Under rotation the spherical harmonic is transformed as:
196 * \f[
197 * Y_{\ell m}({\bf P} \hat{\bf r}) = {\bf P}^{-1}Y_{\ell m}(\hat {\bf r}) =
198 * \sum_{m'} D_{m'm}^{\ell}({\bf P}^{-1}) Y_{\ell m'}(\hat {\bf r}) =
199 * \sum_{m'} D_{mm'}^{\ell}({\bf P}) Y_{\ell m'}(\hat {\bf r})
200 * \f]
201 * so
202 * \f[
203 * \tilde \phi_{\ell m}({\bf r}) =\hat {\bf P}^{-1} \phi_{\ell}(r) Y_{\ell m}(\theta, \phi) =
204 * \sum_{m'} D_{mm'}^{\ell}({\bf P}) \phi_{\ell}(r) Y_{\ell m'}(\theta, \phi)
205 * \f]
206 *
207 * We will use Bloch theorem to get rid of the translations in the argument of \f$ \tilde \phi \f$:
208 * \f[
209 * \int \Psi_{j {\bf k}}^{\sigma *}({\bf r})
210 * \tilde \phi_{\ell m} \big( {\bf r} - {\bf r}_{\beta} - {\bf T}_{P\alpha\beta} - {\bf R}^{-1}{\bf T} \big)
211 * d{\bf r} =
212 * e^{-i{\bf k}({\bf T}_{P\alpha\beta} + {\bf R}^{-1}{\bf T})} \int \Psi_{j {\bf k}}^{\sigma *}({\bf r})
213 * \tilde \phi_{\ell m} \big( {\bf r} - {\bf r}_{\beta} \big) d{\bf r}
214 * \f]
215 * (the "-" in the phase factor appears because KS wave-functions are complex conjugate) and now we can write
216 * \f[
217 * A_{\ell m j\hat {\bf P}{\bf k}}^{\alpha {\bf T} \sigma} =
218 * e^{-i{\bf k}({\bf T}_{P\alpha\beta} + {\bf R}^{-1}{\bf T})}
219 * \sum_{m'} D_{mm'}^{\ell}({\bf P}) A_{\ell m' j{\bf k}}^{\beta \sigma}
220 * \f]
221 *
222 * The final expression for the symmetrized matrix is then
223 * \f[
224 * n_{\ell m \alpha {\bf T} \sigma, \ell' m' \alpha' {\bf T}' \sigma'} =
225 * \sum_{\bf P} \sum_{j} \sum_{{\bf k}}^{IBZ}
226 * A_{\ell m j\hat {\bf P}{\bf k}}^{\alpha {\bf T} \sigma *}
227 * w_{\bf k} n_{j{\bf k}}
228 * A_{\ell' m' j\hat {\bf P}{\bf k}}^{\alpha' {\bf T'} \sigma'} = \\ = \sum_{\bf P} \sum_{j}
229 * \sum_{{\bf k}}^{IBZ}
230 * e^{i{\bf k}({\bf T}_{P\alpha\beta} + {\bf R}^{-1}{\bf T})}
231 * e^{-i{\bf k}({\bf T}_{P\alpha'\beta'} + {\bf R}^{-1}{\bf T'})}
232 * \sum_{m_1 m_2} D_{mm_1}^{\ell *}({\bf P}) D_{m'm_2}^{\ell'}({\bf P})
233 * A_{\ell m_1 j{\bf k}}^{\beta \sigma *} A_{\ell' m_2 j{\bf k}}^{\beta' \sigma'} w_{\bf k} n_{j{\bf k}}
234 * \f]
235 *
236 * In the case of \f$ \alpha = \alpha' \f$ and \f$ {\bf T}={\bf T}' \f$ all the phase-factor exponents disappear
237 * and we get an expression for the "on-site" occupation matrix:
238 *
239 * \f[
240 * n_{\ell m \sigma, \ell' m' \sigma'}^{\alpha} =
241 * \sum_{\bf P} \sum_{j} \sum_{{\bf k}}^{IBZ}
242 * \sum_{m_1 m_2} D_{mm_1}^{\ell *}({\bf P}) D_{m'm_2}^{\ell'}({\bf P})
243 * A_{\ell m_1 j{\bf k}}^{\beta \sigma *} A_{\ell' m_2 j{\bf k}}^{\beta \sigma'}
244 * w_{\bf k} n_{j{\bf k}} = \\ =
245 * \sum_{\bf P} \sum_{m_1 m_2} D_{mm_1}^{\ell *}({\bf P}) D_{m'm_2}^{\ell'}({\bf P})
246 * \tilde n_{\ell m_1 \sigma, \ell' m_2 \sigma'}^{\beta}
247 * \f]
248 *
249 *
250 * To compute the overlap integrals between KS wave-functions and localized Hubbard orbitals we insert
251 * resolution of identity (in \f$ {\bf G+k} \f$ planve-waves) between bra and ket:
252 * \f[
253 * \langle \phi_{\ell m}^{\alpha} | \Psi_{j{\bf k}}^{\sigma} \rangle = \sum_{\bf G}
254 * \phi_{\ell m}^{\alpha *}({\bf G+k}) \Psi_{j}^{\sigma}({\bf G+k})
255 * \f]
256 *
257 */
258inline void symmetrize_density_matrix(Unit_cell const& uc__, density_matrix_t& dm__, int num_mag_comp__)
259{
260 PROFILE("sirius::symmetrize_density_matrix");
261
262 auto& sym = uc__.symmetry();
263
264 /* quick exit */
265 if (sym.size() == 1) {
266 return;
267 }
268
269 density_matrix_t dm_sym(uc__, num_mag_comp__);
270
271 int lmax = uc__.lmax();
272
273 for (int i = 0; i < sym.size(); i++) {
274 int pr = sym[i].spg_op.proper;
275 auto eang = sym[i].spg_op.euler_angles;
276 auto rotm = sht::rotation_matrix<double>(lmax, eang, pr);
277 auto& spin_rot_su2 = sym[i].spin_rotation_su2;
278
279 for (int ia = 0; ia < uc__.num_atoms(); ia++) {
280 int ja = sym[i].spg_op.sym_atom[ia];
281
282 sirius::apply_symmetry_to_density_matrix(dm__[ia], uc__.atom(ia).type().indexb(),
283 num_mag_comp__, rotm, spin_rot_su2, dm_sym[ja]);
284 }
285 }
286
287 double alpha = 1.0 / double(sym.size());
288 /* multiply by alpha which is the inverse of the number of symmetries */
289 for (int ia = 0; ia < uc__.num_atoms(); ia++) {
290 for (size_t i = 0; i < dm__[ia].size(); i++) {
291 dm__[ia][i] = dm_sym[ia][i] * alpha;
292 }
293 }
294}
295
296}
297
298#endif
299
Atom_type const & type() const
Return const reference to corresponding atom type object.
Definition: atom.hpp:318
Representation of a unit cell.
Definition: unit_cell.hpp:43
Atom const & atom(int id__) const
Return const atom instance by id.
Definition: unit_cell.hpp:344
int lmax() const
Maximum orbital quantum number of radial functions between all atom types.
Definition: unit_cell.hpp:526
int num_atoms() const
Number of atoms in the unit cell.
Definition: unit_cell.hpp:338
int lmax(int lmmax__)
Get maximum orbital quantum number by the maximum lm index.
Definition: specfunc.hpp:56
Namespace of the SIRIUS library.
Definition: sirius.f90:5
auto conj(double x__)
Return complex conjugate of a number. For a real value this is the number itself.
Definition: math_tools.hpp:165
void symmetrize_density_matrix(Unit_cell const &uc__, density_matrix_t &dm__, int num_mag_comp__)
Symmetrize density matrix.