SIRIUS 7.5.0
Electronic structure library and applications
atom.hpp
Go to the documentation of this file.
1// Copyright (c) 2013-2017 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 atom.hpp
21 *
22 * \brief Contains declaration and partial implementation of sirius::Atom class.
23 */
24
25#ifndef __ATOM_HPP__
26#define __ATOM_HPP__
27
28#include "core/sht/gaunt.hpp"
29#include "core/profiler.hpp"
32
33namespace sirius {
34
35/// Data and methods specific to the actual atom in the unit cell.
36class Atom
37{
38 private:
39 /// Type of the given atom.
41
42 /// Symmetry class of the given atom.
43 std::shared_ptr<Atom_symmetry_class> symmetry_class_;
44
45 /// Position in fractional coordinates.
47
48 /// Vector field associated with the current site.
50
51 /// Muffin-tin potential.
53
54 /// Radial integrals of the Hamiltonian.
56
57 /// Muffin-tin magnetic field.
59
60 /// Radial integrals of the effective magnetic field.
62
63 /// Maximum l for potential and magnetic field.
64 int lmax_pot_{-1};
65
66 /// Unsymmetrized (sampled over IBZ) occupation matrix of the L(S)DA+U method.
68
69 /// U,J correction matrix of the L(S)DA+U method
71
72 /// True if UJ correction is applied for the current atom.
74
75 /// Orbital quantum number for UJ correction.
77
78 /// Auxiliary form of the D_{ij} operator matrix of the pseudo-potential method.
79 /** The matrix is calculated for the scalar and vector effective fields (thus, it is real and symmetric).
80 * \f[
81 * D_{\xi \xi'}^{\alpha} = \int V({\bf r}) Q_{\xi \xi'}^{\alpha}({\bf r}) d{\bf r}
82 * \f]
83 *
84 * The ionic part of the D-operator matrix is added in the D_operator class, when it is initialized.
85 */
87
88 public:
89 /// Constructor.
90 Atom(Atom_type const& type__, r3::vector<double> position__, r3::vector<double> vector_field__)
91 : type_(type__)
92 , position_(position__)
93 , vector_field_(vector_field__)
94 {
95 }
96
97 /// Initialize atom.
98 inline void init()
99 {
100 lmax_pot_ = type().parameters().lmax_pot();
101
102 if (type().parameters().full_potential()) {
104 int nrf = type().indexr().size();
105
108
109 if (type().parameters().num_mag_dims()) {
112 }
113
115
117 }
118
119 if (!type().parameters().full_potential()) {
120 int nbf = type().mt_basis_size();
121 d_mtrx_ = sddk::mdarray<double, 3>(nbf, nbf, type().parameters().num_mag_dims() + 1, sddk::memory_t::host,
122 "Atom::d_mtrx_");
123 d_mtrx_.zero();
124 }
125 }
126
127 /// Generate radial Hamiltonian and effective magnetic field integrals
128 /** Hamiltonian operator has the following representation inside muffin-tins:
129 * \f[
130 * \hat H = -\frac{1}{2}\nabla^2 + \sum_{\ell m} V_{\ell m}(r) R_{\ell m}(\hat {\bf r}) =
131 * \underbrace{-\frac{1}{2} \nabla^2+V_{00}(r)R_{00}}_{H_{s}(r)} +\sum_{\ell=1} \sum_{m=-\ell}^{\ell}
132 * V_{\ell m}(r) R_{\ell m}(\hat {\bf r}) = \sum_{\ell m} \widetilde V_{\ell m}(r) R_{\ell m}(\hat {\bf r})
133 * \f]
134 * where
135 * \f[
136 * \widetilde V_{\ell m}(r) = \left\{ \begin{array}{ll}
137 * \frac{H_{s}(r)}{R_{00}} & \ell = 0 \\
138 * V_{\ell m}(r) & \ell > 0 \end{array} \right.
139 * \f]
140 */
142 {
143 PROFILE("sirius::Atom::generate_radial_integrals");
144
146 int nmtp = type().num_mt_points();
147 int nrf = type().indexr().size();
148 int num_mag_dims = type().parameters().num_mag_dims();
149
150 if (comm__.size() != 1) {
151 RTE_THROW("not yet mpi parallel");
152 }
153
154 splindex_block<> spl_lm(lmmax, n_blocks(comm__.size()), block_id(comm__.rank()));
155
157
159 if (num_mag_dims) {
161 }
162
163 /* copy radial functions to spline objects */
164 std::vector<Spline<double>> rf_spline(nrf);
165 #pragma omp parallel for
166 for (int i = 0; i < nrf; i++) {
167 rf_spline[i] = Spline<double>(type().radial_grid());
168 for (int ir = 0; ir < nmtp; ir++) {
169 rf_spline[i](ir) = symmetry_class().radial_function(ir, i);
170 }
171 }
172
173 /* copy effective potential components to spline objects */
174 std::vector<Spline<double>> v_spline(lmmax * (1 + num_mag_dims));
175 #pragma omp parallel for
176 for (int lm = 0; lm < lmmax; lm++) {
177 v_spline[lm] = Spline<double>(type().radial_grid());
178 for (int ir = 0; ir < nmtp; ir++) {
179 v_spline[lm](ir) = veff_(lm, ir);
180 }
181
182 for (int j = 0; j < num_mag_dims; j++) {
183 v_spline[lm + (j + 1) * lmmax] = Spline<double>(type().radial_grid());
184 for (int ir = 0; ir < nmtp; ir++) {
185 v_spline[lm + (j + 1) * lmmax](ir) = beff_[j](lm, ir);
186 }
187 }
188 }
189
190 /* interpolate potential multiplied by a radial function */
191 std::vector<Spline<double>> vrf_spline(lmmax * nrf * (1 + num_mag_dims));
192
193 auto& idx_ri = type().idx_radial_integrals();
194
195 sddk::mdarray<double, 1> result(idx_ri.size(1));
196
197 if (pu__ == sddk::device_t::GPU) {
198#ifdef SIRIUS_GPU
199 auto& rgrid = type().radial_grid();
200 auto& rf_coef = type().rf_coef();
201 auto& vrf_coef = type().vrf_coef();
202
203 PROFILE_START("sirius::Atom::generate_radial_integrals|interp");
204 #pragma omp parallel
205 {
206 #pragma omp for
207 for (int i = 0; i < nrf; i++) {
208 rf_spline[i].interpolate();
209 std::copy(rf_spline[i].coeffs().at(sddk::memory_t::host),
210 rf_spline[i].coeffs().at(sddk::memory_t::host) + nmtp * 4,
211 rf_coef.at(sddk::memory_t::host, 0, 0, i));
212 // cuda_async_copy_to_device(rf_coef.at<GPU>(0, 0, i), rf_coef.at<CPU>(0, 0, i), nmtp * 4 *
213 // sizeof(double), tid);
214 }
215 #pragma omp for
216 for (int i = 0; i < lmmax * (1 + num_mag_dims); i++) {
217 v_spline[i].interpolate();
218 }
219 }
220 rf_coef.copy_to(sddk::memory_t::device, acc::stream_id(-1));
221
222 #pragma omp parallel for
223 for (int lm = 0; lm < lmmax; lm++) {
224 for (int i = 0; i < nrf; i++) {
225 for (int j = 0; j < num_mag_dims + 1; j++) {
226 int idx = lm + lmmax * i + lmmax * nrf * j;
227 vrf_spline[idx] = rf_spline[i] * v_spline[lm + j * lmmax];
228 std::memcpy(vrf_coef.at(sddk::memory_t::host, 0, 0, idx), vrf_spline[idx].coeffs().at(sddk::memory_t::host),
229 nmtp * 4 * sizeof(double));
230 // cuda_async_copy_to_device(vrf_coef.at<GPU>(0, 0, idx), vrf_coef.at<CPU>(0, 0, idx), nmtp * 4
231 // *sizeof(double), tid);
232 }
233 }
234 }
235 vrf_coef.copy_to(sddk::memory_t::device);
236 PROFILE_STOP("sirius::Atom::generate_radial_integrals|interp");
237
238 result.allocate(sddk::memory_t::device);
239 spline_inner_product_gpu_v3(idx_ri.at(sddk::memory_t::device), (int)idx_ri.size(1), nmtp,
240 rgrid.x().at(sddk::memory_t::device), rgrid.dx().at(sddk::memory_t::device),
241 rf_coef.at(sddk::memory_t::device), vrf_coef.at(sddk::memory_t::device),
242 result.at(sddk::memory_t::device));
243 acc::sync();
244 //if (type().parameters().control().print_performance_) {
245 // double tval = t2.stop();
246 // DUMP("spline GPU integration performance: %12.6f GFlops",
247 // 1e-9 * double(idx_ri.size(1)) * nmtp * 85 / tval);
248 //}
249 result.copy_to(sddk::memory_t::host);
250 result.deallocate(sddk::memory_t::device);
251#endif
252 }
253 if (pu__ == sddk::device_t::CPU) {
254 PROFILE_START("sirius::Atom::generate_radial_integrals|interp");
255 #pragma omp parallel
256 {
257 #pragma omp for
258 for (int i = 0; i < nrf; i++) {
259 rf_spline[i].interpolate();
260 }
261 #pragma omp for
262 for (int i = 0; i < lmmax * (1 + num_mag_dims); i++) {
263 v_spline[i].interpolate();
264 }
265
266 #pragma omp for
267 for (int lm = 0; lm < lmmax; lm++) {
268 for (int i = 0; i < nrf; i++) {
269 for (int j = 0; j < num_mag_dims + 1; j++) {
270 vrf_spline[lm + lmmax * i + lmmax * nrf * j] = rf_spline[i] * v_spline[lm + j * lmmax];
271 }
272 }
273 }
274 }
275 PROFILE_STOP("sirius::Atom::generate_radial_integrals|interp");
276
277 PROFILE("sirius::Atom::generate_radial_integrals|inner");
278 #pragma omp parallel for
279 for (int j = 0; j < (int)idx_ri.size(1); j++) {
280 result(j) = inner(rf_spline[idx_ri(0, j)], vrf_spline[idx_ri(1, j)], 2);
281 }
282 //if (type().parameters().control().print_performance_) {
283 // double tval = t2.stop();
284 // DUMP("spline CPU integration performance: %12.6f GFlops",
285 // 1e-9 * double(idx_ri.size(1)) * nmtp * 85 / tval);
286 //}
287 }
288
289 int n{0};
290 for (int lm = 0; lm < lmmax; lm++) {
291 int l = l_by_lm[lm];
292
293 for (int i2 = 0; i2 < type().indexr().size(); i2++) {
294 int l2 = type().indexr(i2).am.l();
295 for (int i1 = 0; i1 <= i2; i1++) {
296 int l1 = type().indexr(i1).am.l();
297 if ((l + l1 + l2) % 2 == 0) {
298 if (lm) {
299 h_radial_integrals_(lm, i1, i2) = h_radial_integrals_(lm, i2, i1) = result(n++);
300 } else {
301 h_radial_integrals_(0, i1, i2) = symmetry_class().h_spherical_integral(i1, i2);
302 h_radial_integrals_(0, i2, i1) = symmetry_class().h_spherical_integral(i2, i1);
303 }
304 for (int j = 0; j < num_mag_dims; j++) {
305 b_radial_integrals_(lm, i1, i2, j) = b_radial_integrals_(lm, i2, i1, j) = result(n++);
306 }
307 }
308 }
309 }
310 }
311
312 //if (type().parameters().control().print_checksum_) {
313 // DUMP("checksum(h_radial_integrals): %18.10f", h_radial_integrals_.checksum());
314 //}
315 }
316
317 /// Return const reference to corresponding atom type object.
318 inline Atom_type const& type() const
319 {
320 return type_;
321 }
322
323 /// Return reference to corresponding atom symmetry class.
325 {
326 return (*symmetry_class_);
327 }
328
329 /// Return const referenced to atom symmetry class.
331 {
332 return (*symmetry_class_);
333 }
334
335 /// Return atom type id.
336 inline int type_id() const
337 {
338 return type_.id();
339 }
340
341 /// Return atom position in fractional coordinates.
342 inline r3::vector<double> const& position() const
343 {
344 return position_;
345 }
346
347 /// Set atom position in fractional coordinates.
348 inline void set_position(r3::vector<double> position__)
349 {
350 position_ = position__;
351 }
352
353 /// Return vector field.
354 inline auto vector_field() const
355 {
356 return vector_field_;
357 }
358
359 /// Return id of the symmetry class.
360 inline int symmetry_class_id() const
361 {
362 if (symmetry_class_ != nullptr) {
363 return symmetry_class_->id();
364 }
365 return -1;
366 }
367
368 /// Set symmetry class of the atom.
369 inline void set_symmetry_class(std::shared_ptr<Atom_symmetry_class> symmetry_class__)
370 {
371 symmetry_class_ = std::move(symmetry_class__);
372 }
373
374 /// Set muffin-tin potential and magnetic field.
375 inline void set_nonspherical_potential(double* veff__, double* beff__[3])
376 {
377 veff_ = sddk::mdarray<double, 2>(veff__, sf::lmmax(lmax_pot_), type().num_mt_points());
378 for (int j = 0; j < 3; j++) {
379 beff_[j] = sddk::mdarray<double, 2>(beff__[j], sf::lmmax(lmax_pot_), type().num_mt_points());
380 }
381 }
382
383 inline void sync_radial_integrals(mpi::Communicator const& comm__, int const rank__)
384 {
385 comm__.bcast(h_radial_integrals_.at(sddk::memory_t::host), (int)h_radial_integrals_.size(), rank__);
386 if (type().parameters().num_mag_dims()) {
387 comm__.bcast(b_radial_integrals_.at(sddk::memory_t::host), (int)b_radial_integrals_.size(), rank__);
388 }
389 }
390
391 inline void sync_occupation_matrix(mpi::Communicator const& comm__, int const rank__)
392 {
393 comm__.bcast(occupation_matrix_.at(sddk::memory_t::host), (int)occupation_matrix_.size(), rank__);
394 }
395
396 inline double const* h_radial_integrals(int idxrf1, int idxrf2) const
397 {
398 return &h_radial_integrals_(0, idxrf1, idxrf2);
399 }
400
401 inline double* h_radial_integrals(int idxrf1, int idxrf2)
402 {
403 return &h_radial_integrals_(0, idxrf1, idxrf2);
404 }
405
406 inline double const* b_radial_integrals(int idxrf1, int idxrf2, int x) const
407 {
408 return &b_radial_integrals_(0, idxrf1, idxrf2, x);
409 }
410
411 /** Compute the following kinds of sums for different spin-blocks of the Hamiltonian:
412 * \f[
413 * \sum_{L_3} \langle Y_{L_1} u_{\ell_1 \nu_1} | R_{L_3} h_{L_3} | Y_{L_2} u_{\ell_2 \nu_2} \rangle =
414 * \sum_{L_3} \langle u_{\ell_1 \nu_1} | h_{L_3} | u_{\ell_2 \nu_2} \rangle
415 * \langle Y_{L_1} | R_{L_3} | Y_{L_2} \rangle
416 * \f]
417 */
418 template <spin_block_t sblock>
419 inline std::complex<double>
420 radial_integrals_sum_L3(int idxrf1__, int idxrf2__, std::vector<gaunt_L3<std::complex<double>>> const& gnt__) const
421 {
422 std::complex<double> zsum(0, 0);
423
424 for (size_t i = 0; i < gnt__.size(); i++) {
425 switch (sblock) {
426 case spin_block_t::nm: {
427 /* just the Hamiltonian */
428 zsum += gnt__[i].coef * h_radial_integrals_(gnt__[i].lm3, idxrf1__, idxrf2__);
429 break;
430 }
431 case spin_block_t::uu: {
432 /* h + Bz */
433 zsum += gnt__[i].coef * (h_radial_integrals_(gnt__[i].lm3, idxrf1__, idxrf2__) +
434 b_radial_integrals_(gnt__[i].lm3, idxrf1__, idxrf2__, 0));
435 break;
436 }
437 case spin_block_t::dd: {
438 /* h - Bz */
439 zsum += gnt__[i].coef * (h_radial_integrals_(gnt__[i].lm3, idxrf1__, idxrf2__) -
440 b_radial_integrals_(gnt__[i].lm3, idxrf1__, idxrf2__, 0));
441 break;
442 }
443 case spin_block_t::ud: {
444 /* Bx - i By */
445 zsum += gnt__[i].coef * std::complex<double>(b_radial_integrals_(gnt__[i].lm3, idxrf1__, idxrf2__, 1),
446 -b_radial_integrals_(gnt__[i].lm3, idxrf1__, idxrf2__, 2));
447 break;
448 }
449 case spin_block_t::du: {
450 /* Bx + i By */
451 zsum += gnt__[i].coef * std::complex<double>(b_radial_integrals_(gnt__[i].lm3, idxrf1__, idxrf2__, 1),
452 b_radial_integrals_(gnt__[i].lm3, idxrf1__, idxrf2__, 2));
453 break;
454 }
455 }
456 }
457 return zsum;
458 }
459
460 inline int num_mt_points() const
461 {
462 return type_.num_mt_points();
463 }
464
465 inline Radial_grid<double> const& radial_grid() const
466 {
467 return type_.radial_grid();
468 }
469
470 inline double radial_grid(int idx) const
471 {
472 return type_.radial_grid(idx);
473 }
474
475 inline double mt_radius() const
476 {
477 return type_.mt_radius();
478 }
479
480 inline int zn() const
481 {
482 return type_.zn();
483 }
484
485 inline int mt_basis_size() const
486 {
487 return type_.mt_basis_size();
488 }
489
490 inline int mt_aw_basis_size() const
491 {
492 return type_.mt_aw_basis_size();
493 }
494
495 inline int mt_lo_basis_size() const
496 {
497 return type_.mt_lo_basis_size();
498 }
499
500 inline void set_occupation_matrix(const std::complex<double>* source)
501 {
502 std::memcpy(occupation_matrix_.at(sddk::memory_t::host), source, 16 * 16 * 2 * 2 * sizeof(std::complex<double>));
503 apply_uj_correction_ = false;
504 }
505
506 inline void get_occupation_matrix(std::complex<double>* destination)
507 {
508 std::memcpy(destination, occupation_matrix_.at(sddk::memory_t::host), 16 * 16 * 2 * 2 * sizeof(std::complex<double>));
509 }
510
511 inline void set_uj_correction_matrix(const int l, const std::complex<double>* source)
512 {
514 std::memcpy(uj_correction_matrix_.at(sddk::memory_t::host), source, 16 * 16 * 2 * 2 * sizeof(std::complex<double>));
516 }
517
518 inline bool apply_uj_correction()
519 {
521 }
522
523 inline int uj_correction_l()
524 {
525 return uj_correction_l_;
526 }
527
528 inline auto uj_correction_matrix(int lm1, int lm2, int ispn1, int ispn2)
529 {
530 return uj_correction_matrix_(lm1, lm2, ispn1, ispn2);
531 }
532
533 inline double& d_mtrx(int xi1, int xi2, int iv)
534 {
535 return d_mtrx_(xi1, xi2, iv);
536 }
537
538 inline double const& d_mtrx(int xi1, int xi2, int iv) const
539 {
540 return d_mtrx_(xi1, xi2, iv);
541 }
542
543 inline auto const& d_mtrx() const
544 {
545 return d_mtrx_;
546 }
547
548 inline auto& d_mtrx()
549 {
550 return d_mtrx_;
551 }
552};
553
554} // namespace
555
556#endif // __ATOM_H__
Contains declaration and partial implementation of sirius::Atom_symmetry_class class.
Data and methods specific to the symmetry class of the atom.
double radial_function(int ir, int idx) const
Get a value of the radial functions.
Defines the properties of atom type.
Definition: atom_type.hpp:93
int mt_basis_size() const
Total number of muffin-tin basis functions (APW + LO).
Definition: atom_type.hpp:880
int num_mt_points() const
Return number of muffin-tin radial grid points.
Definition: atom_type.hpp:718
auto const & indexr() const
Return const reference to the index of radial functions.
Definition: atom_type.hpp:817
int zn() const
Return ionic charge (as positive integer).
Definition: atom_type.hpp:681
double mt_radius() const
Return muffin-tin radius.
Definition: atom_type.hpp:712
int id() const
Return atom type id.
Definition: atom_type.hpp:675
Data and methods specific to the actual atom in the unit cell.
Definition: atom.hpp:37
int type_id() const
Return atom type id.
Definition: atom.hpp:336
std::shared_ptr< Atom_symmetry_class > symmetry_class_
Symmetry class of the given atom.
Definition: atom.hpp:43
void set_position(r3::vector< double > position__)
Set atom position in fractional coordinates.
Definition: atom.hpp:348
sddk::mdarray< double, 2 > beff_[3]
Muffin-tin magnetic field.
Definition: atom.hpp:58
Atom_type const & type_
Type of the given atom.
Definition: atom.hpp:40
bool apply_uj_correction_
True if UJ correction is applied for the current atom.
Definition: atom.hpp:73
Atom_symmetry_class & symmetry_class()
Return reference to corresponding atom symmetry class.
Definition: atom.hpp:324
std::complex< double > radial_integrals_sum_L3(int idxrf1__, int idxrf2__, std::vector< gaunt_L3< std::complex< double > > > const &gnt__) const
Definition: atom.hpp:420
Atom_symmetry_class const & symmetry_class() const
Return const referenced to atom symmetry class.
Definition: atom.hpp:330
sddk::mdarray< double, 2 > veff_
Muffin-tin potential.
Definition: atom.hpp:52
sddk::mdarray< double, 3 > d_mtrx_
Auxiliary form of the D_{ij} operator matrix of the pseudo-potential method.
Definition: atom.hpp:86
Atom(Atom_type const &type__, r3::vector< double > position__, r3::vector< double > vector_field__)
Constructor.
Definition: atom.hpp:90
void set_symmetry_class(std::shared_ptr< Atom_symmetry_class > symmetry_class__)
Set symmetry class of the atom.
Definition: atom.hpp:369
int lmax_pot_
Maximum l for potential and magnetic field.
Definition: atom.hpp:64
void generate_radial_integrals(sddk::device_t pu__, mpi::Communicator const &comm__)
Generate radial Hamiltonian and effective magnetic field integrals.
Definition: atom.hpp:141
void init()
Initialize atom.
Definition: atom.hpp:98
sddk::mdarray< std::complex< double >, 4 > occupation_matrix_
Unsymmetrized (sampled over IBZ) occupation matrix of the L(S)DA+U method.
Definition: atom.hpp:67
void set_nonspherical_potential(double *veff__, double *beff__[3])
Set muffin-tin potential and magnetic field.
Definition: atom.hpp:375
sddk::mdarray< double, 3 > h_radial_integrals_
Radial integrals of the Hamiltonian.
Definition: atom.hpp:55
r3::vector< double > position_
Position in fractional coordinates.
Definition: atom.hpp:46
sddk::mdarray< std::complex< double >, 4 > uj_correction_matrix_
U,J correction matrix of the L(S)DA+U method.
Definition: atom.hpp:70
sddk::mdarray< double, 4 > b_radial_integrals_
Radial integrals of the effective magnetic field.
Definition: atom.hpp:61
Atom_type const & type() const
Return const reference to corresponding atom type object.
Definition: atom.hpp:318
auto vector_field() const
Return vector field.
Definition: atom.hpp:354
r3::vector< double > const & position() const
Return atom position in fractional coordinates.
Definition: atom.hpp:342
int uj_correction_l_
Orbital quantum number for UJ correction.
Definition: atom.hpp:76
int symmetry_class_id() const
Return id of the symmetry class.
Definition: atom.hpp:360
r3::vector< double > vector_field_
Vector field associated with the current site.
Definition: atom.hpp:49
Helper class to wrap stream id (integer number).
Definition: acc.hpp:132
MPI communicator wrapper.
void bcast(T *buffer__, int count__, int root__) const
Perform buffer broadcast.
int size() const
Size of the communicator (number of ranks).
int rank() const
Rank of MPI process inside communicator.
void copy_to(memory_t mem__, size_t idx0__, size_t n__, acc::stream_id sid=acc::stream_id(-1))
Copy n elements starting from idx0 from one memory type to another.
Definition: memory.hpp:1339
void zero(memory_t mem__, size_t idx0__, size_t n__)
Zero n elements starting from idx0.
Definition: memory.hpp:1316
void deallocate(memory_t memory__)
Deallocate host or device memory.
Definition: memory.hpp:1104
mdarray< T, N > & allocate(memory_t memory__)
Allocate memory for array.
Definition: memory.hpp:1057
size_t size() const
Return total size (number of elements) of the array.
Definition: memory.hpp:1207
Contains definition and implementation of sirius::Gaunt class.
device_t
Type of the main processing unit.
Definition: memory.hpp:120
void sync()
Synchronize device.
Definition: acc.hpp:249
void copy(T *target__, T const *source__, size_t n__)
Copy memory inside a device.
Definition: acc.hpp:320
int lmmax(int lmax)
Maximum number of combinations for a given .
Definition: specfunc.hpp:44
int lm(int l, int m)
Get composite lm index by angular index l and azimuthal index m.
Definition: specfunc.hpp:50
std::vector< int > l_by_lm(int lmax__)
Get array of orbital quantum numbers for each lm component.
Definition: specfunc.hpp:69
std::enable_if_t< std::is_same< T, real_type< F > >::value, void > inner(::spla::Context &spla_ctx__, sddk::memory_t mem__, spin_range spins__, W const &wf_i__, band_range br_i__, Wave_functions< T > const &wf_j__, band_range br_j__, la::dmatrix< F > &result__, int irow0__, int jcol0__)
Compute inner product between the two sets of wave-functions.
Namespace of the SIRIUS library.
Definition: sirius.f90:5
@ du
Down-up block.
@ dd
Down-donw block.
@ ud
Up-down block.
@ uu
Up-up block.
@ nm
Non-magnetic case.
strong_type< int, struct __n_blocks_tag > n_blocks
Number of blocks to which the global index is split.
Definition: splindex.hpp:105
A time-based profiler.
Contains declaration and implementation of sirius::Spheric_function and sirius::Spheric_function_grad...
Used in the {lm1, lm2} : {lm3, coefficient} way of grouping non-zero Gaunt coefficients.
Definition: gaunt.hpp:37