25#ifndef __AUGMENTATION_OPERATOR_HPP__
26#define __AUGMENTATION_OPERATOR_HPP__
31#if defined(SIRIUS_GPU)
35aug_op_pw_coeffs_gpu(
int ngvec__,
int const* gvec_shell__,
int const* idx__,
int idxmax__,
36 std::complex<double>
const* zilm__,
int const* l_by_lm__,
int lmmax__,
double const* gc__,
int ld0__,
37 int ld1__,
double const* gvec_rlm__,
int ld2__,
double const* ri_values__,
int ld3__,
int ld4__,
38 double* q_pw__,
int ld5__,
double fourpi_omega__);
41aug_op_pw_coeffs_deriv_gpu(
int ngvec__,
int const* gvec_shell__,
double const* gvec_cart__,
int const* idx__,
42 int idxmax__,
double const* gc__,
int ld0__,
int ld1__,
double const* rlm__,
double const* rlm_dg__,
int ld2__,
43 double const* ri_values__,
double const* ri_dg_values__,
int ld3__,
int ld4__,
double* q_pw__,
int ld5__,
44 double fourpi__,
int nu__,
int lmax_q__);
47spherical_harmonics_rlm_gpu(
int lmax__,
int ntp__,
double const* theta__,
double const* phi__,
double* rlm__,
int ld__);
55inline void iterate_aug_atom_types(Unit_cell
const& uc__, F&& f__)
57 for (
int iat = 0; iat < uc__.num_atom_types(); iat++) {
58 auto& atom_type = uc__.atom_type(iat);
60 if (!atom_type.augment() || atom_type.num_atoms() == 0) {
67inline auto max_l_aug(Unit_cell
const& uc__)
71 iterate_aug_atom_types(uc__,
72 [&l](Atom_type
const& type__)
74 l = std::max(l, type__.indexr().lmax());
80inline auto max_na_aug(Unit_cell
const& uc__)
84 iterate_aug_atom_types(uc__,
85 [&na](Atom_type
const& type__)
87 na = std::max(na, type__.num_atoms());
94inline auto max_nb_aug(Unit_cell
const& uc__)
98 iterate_aug_atom_types(uc__,
99 [&nb](Atom_type
const& type__)
101 nb = std::max(nb, type__.mt_basis_size());
140 : atom_type_(atom_type__)
143 int lmax_beta = atom_type_.
indexr().lmax();
144 int lmax = 2 * lmax_beta;
154 for (
int l = 0,
lm = 0; l <=
lmax; l++) {
155 for (
int m = -l; m <= l; m++,
lm++) {
156 zilm_[
lm] = std::pow(std::complex<double>(0, 1), l);
165 int nqlm = nbf * (nbf + 1) / 2;
169 for (
int xi2 = 0; xi2 < nbf; xi2++) {
170 int lm2 = atom_type_.indexb(xi2).lm;
171 int idxrf2 = atom_type_.indexb(xi2).idxrf;
173 for (
int xi1 = 0; xi1 <= xi2; xi1++) {
174 int lm1 = atom_type_.indexb(xi1).lm;
175 int idxrf1 = atom_type_.indexb(xi1).idxrf;
182 idx_(0, idx12) = lm1;
183 idx_(1, idx12) = lm2;
184 idx_(2, idx12) = idxrf12;
190 #pragma omp parallel for
191 for (
int j = 0; j < gvec_.num_gvec_shells_local(); j++) {
192 auto ri = ri__.values(atom_type_.
id(), gvec_.gvec_shell_len_local(j));
193 auto ri_dq = ri_dq__.values(atom_type__.
id(), gvec_.gvec_shell_len_local(j));
194 for (
int l = 0; l <=
lmax; l++) {
195 for (
int i = 0; i < nbrf * (nbrf + 1) / 2; i++) {
196 ri_values_(i, l, j) = ri(i, l);
197 ri_dq_values_(i, l, j) = ri_dq(i, l);
203 for (
int xi2 = 0; xi2 < nbf; xi2++) {
204 for (
int xi1 = 0; xi1 <= xi2; xi1++) {
207 sym_weight_(idx12) = (xi1 == xi2) ? 1 : 2;
211 if (atom_type_.parameters().processing_unit() == sddk::device_t::GPU) {
212 auto& mpd = sddk::get_memory_pool(sddk::memory_t::device);
213 sym_weight_.
allocate(mpd).copy_to(sddk::memory_t::device);
217 auto mt = (atom_type_.parameters().processing_unit() == sddk::device_t::CPU) ? sddk::memory_t::host :
218 sddk::memory_t::host_pinned;
255 auto const& q_pw()
const
260 double q_pw(
int i__,
int ig__)
const
262 return q_pw_(i__, ig__);
266 inline double q_mtrx(
int xi1__,
int xi2__)
const
268 return q_mtrx_(xi1__, xi2__);
271 inline auto const& sym_weight()
const
280 return sym_weight_(idx__);
Defines the properties of atom type.
int mt_basis_size() const
Total number of muffin-tin basis functions (APW + LO).
auto const & indexr() const
Return const reference to the index of radial functions.
int mt_radial_basis_size() const
Total number of radial basis functions.
int id() const
Return atom type id.
Augmentation charge operator Q(r) of the ultrasoft pseudopotential formalism.
void generate_pw_coeffs()
Generate Q_{xi,xi'}(G) plane wave coefficients.
Augmentation_operator(Atom_type const &atom_type__, fft::Gvec const &gvec__, Radial_integrals_aug< false > const &ri__, Radial_integrals_aug< true > const &ri_dq__)
Constructor.
double sym_weight(int idx__) const
Weight of Q_{\xi,\xi'}.
double q_mtrx(int xi1__, int xi2__) const
Get values of the Q-matrix.
void generate_pw_coeffs_gvec_deriv(int nu__)
Generate G-vector derivative Q_{xi,xi'}(G)/dG of the plane-wave coefficients */.
Radial integrals of the augmentation operator.
A set of G-vectors for FFTs and G+k basis functions.
int count() const
Number of G-vectors for a fine-grained distribution for the current MPI rank.
mdarray< T, N > & allocate(memory_t memory__)
Allocate memory for array.
Declaration and implementation of Gvec class.
void copy(T *target__, T const *source__, size_t n__)
Copy memory inside a device.
int lmax(int lmmax__)
Get maximum orbital quantum number by the maximum lm index.
int lmmax(int lmax)
Maximum number of combinations for a given .
int lm(int l, int m)
Get composite lm index by angular index l and azimuthal index m.
std::vector< int > l_by_lm(int lmax__)
Get array of orbital quantum numbers for each lm component.
Namespace of the SIRIUS library.
int packed_index(int i__, int j__)
Pack two indices into one for symmetric matrices.
Representation of various radial integrals.