29template <
bool jl_deriv>
32 PROFILE(
"sirius::Radial_integrals|atomic_wfs");
37 for (
int iat = 0; iat < unit_cell_.num_atom_types(); iat++) {
39 auto& atom_type = unit_cell_.atom_type(iat);
41 int nwf = indexr_(iat).size();
47 #pragma omp parallel for
48 for (
int iq = 0; iq < nq(); iq++) {
53 for (
int i = 0; i < nwf; i++) {
56 int l = indexr_(iat).am(
rf_index(i)).l();
57 auto& rwf = fl__(iat, i);
59 #pragma omp parallel for
60 for (
int iq = 0; iq < nq(); iq++) {
62 auto s = jl(iq).deriv_q(l);
63 values_(i, iat)(iq) = sirius::inner(s, rwf, 1);
65 values_(i, iat)(iq) = sirius::inner(jl(iq)[l], rwf, 1);
69 values_(i, iat).interpolate();
74template<
bool jl_deriv>
77 PROFILE(
"sirius::Radial_integrals|aug");
80 for (
int iat = 0; iat < unit_cell_.num_atom_types(); iat++) {
81 auto& atom_type = unit_cell_.atom_type(iat);
83 if (!atom_type.augment()) {
88 int nbrf = atom_type.mt_radial_basis_size();
90 int lmax_beta = atom_type.indexr().lmax();
92 for (
int l = 0; l <= 2 * lmax_beta; l++) {
93 for (
int idx = 0; idx < nbrf * (nbrf + 1) / 2; idx++) {
94 values_(idx, l, iat) = Spline<double>(grid_q_);
98 #pragma omp parallel for
99 for (
auto it : spl_q_) {
102 sf::Spherical_Bessel_functions jl(2 * lmax_beta, atom_type.radial_grid(), grid_q_[iq]);
104 for (
int l3 = 0; l3 <= 2 * lmax_beta; l3++) {
105 for (
int idxrf2 = 0; idxrf2 < nbrf; idxrf2++) {
106 int l2 = atom_type.indexr(idxrf2).am.l();
107 for (
int idxrf1 = 0; idxrf1 <= idxrf2; idxrf1++) {
108 int l1 = atom_type.indexr(idxrf1).am.l();
110 int idx = idxrf2 * (idxrf2 + 1) / 2 + idxrf1;
112 if (l3 >= std::abs(l1 - l2) && l3 <= (l1 + l2) && (l1 + l2 + l3) % 2 == 0) {
114 auto s = jl.deriv_q(l3);
115 values_(idx, l3, iat)(iq) =
116 sirius::inner(s, atom_type.q_radial_function(idxrf1, idxrf2, l3), 0);
118 values_(idx, l3, iat)(iq) =
119 sirius::inner(jl[l3], atom_type.q_radial_function(idxrf1, idxrf2, l3), 0);
126 for (
int l = 0; l <= 2 * lmax_beta; l++) {
127 for (
int idx = 0; idx < nbrf * (nbrf + 1) / 2; idx++) {
128 unit_cell_.comm().allgather(&values_(idx, l, iat)(0), spl_q_.local_size(), spl_q_.global_offset());
132 #pragma omp parallel for
133 for (
int l = 0; l <= 2 * lmax_beta; l++) {
134 for (
int idx = 0; idx < nbrf * (nbrf + 1) / 2; idx++) {
135 values_(idx, l, iat).interpolate();
141void Radial_integrals_rho_pseudo::generate()
143 PROFILE(
"sirius::Radial_integrals|rho_pseudo");
148 if (atom_type.ps_total_charge_density().empty()) {
154 Spline<double> rho(atom_type.radial_grid(), atom_type.ps_total_charge_density());
156 #pragma omp parallel for
159 sf::Spherical_Bessel_functions jl(0, atom_type.radial_grid(),
grid_q_[iq]);
161 values_(iat)(iq) = sirius::inner(jl[0], rho, 0, atom_type.num_mt_points()) /
fourpi;
168template<
bool jl_deriv>
169void Radial_integrals_rho_core_pseudo<jl_deriv>::generate()
171 PROFILE(
"sirius::Radial_integrals|rho_core_pseudo");
173 for (
int iat = 0; iat < unit_cell_.num_atom_types(); iat++) {
174 auto& atom_type = unit_cell_.atom_type(iat);
176 if (atom_type.ps_core_charge_density().empty()) {
180 values_(iat) = Spline<double>(grid_q_);
182 Spline<double> ps_core(atom_type.radial_grid(), atom_type.ps_core_charge_density());
184 #pragma omp parallel for
185 for (
auto it : spl_q_) {
187 sf::Spherical_Bessel_functions jl(0, atom_type.radial_grid(), grid_q_[iq]);
190 auto s = jl.deriv_q(0);
191 values_(iat)(iq) = sirius::inner(s, ps_core, 2, atom_type.num_mt_points());
193 values_(iat)(iq) = sirius::inner(jl[0], ps_core, 2, atom_type.num_mt_points());
196 unit_cell_.comm().allgather(&values_(iat)(0), spl_q_.local_size(), spl_q_.global_offset());
197 values_(iat).interpolate();
201template<
bool jl_deriv>
204 PROFILE(
"sirius::Radial_integrals|beta");
206 for (
int iat = 0; iat < unit_cell_.num_atom_types(); iat++) {
207 auto& atom_type = unit_cell_.atom_type(iat);
208 int nrb = atom_type.num_beta_radial_functions();
214 for (
int idxrf = 0; idxrf < nrb; idxrf++) {
218 #pragma omp parallel for
219 for (
auto it : spl_q_) {
222 for (
int idxrf = 0; idxrf < nrb; idxrf++) {
223 int l = atom_type.indexr(idxrf).am.l();
228 values_(idxrf, iat)(iq) = sirius::inner(s, atom_type.beta_radial_function(
rf_index(idxrf)).second, 1);
230 values_(idxrf, iat)(iq) = sirius::inner(jl[l], atom_type.beta_radial_function(
rf_index(idxrf)).second, 1);
235 for (
int idxrf = 0; idxrf < nrb; idxrf++) {
236 unit_cell_.comm().allgather(&values_(idxrf, iat)(0), spl_q_.local_size(), spl_q_.global_offset());
237 values_(idxrf, iat).interpolate();
242template <
bool jl_deriv>
245 PROFILE(
"sirius::Radial_integrals|vloc");
247 for (
int iat = 0; iat < unit_cell_.num_atom_types(); iat++) {
248 auto& atom_type = unit_cell_.atom_type(iat);
250 if (atom_type.local_potential().empty()) {
254 values_(iat) = Spline<double>(grid_q_);
256 auto& vloc = atom_type.local_potential();
258 int np = atom_type.num_mt_points();
267 int np1 = atom_type.radial_grid().index_of(10);
273 auto rg = atom_type.radial_grid().segment(np);
275 #pragma omp parallel for
276 for (
auto it : spl_q_) {
278 Spline<double> s(rg);
279 double g = grid_q_[iq];
282 for (
int ir = 0; ir < rg.num_points(); ir++) {
284 s(ir) = (x * vloc[ir] + atom_type.zn() * std::erf(x)) * (std::sin(g * x) - g * x * std::cos(g * x));
288 for (
int ir = 0; ir < rg.num_points(); ir++) {
291 s(ir) = (x * vloc[ir] + atom_type.zn()) * x;
294 for (
int ir = 0; ir < rg.num_points(); ir++) {
297 s(ir) = (x * vloc[ir] + atom_type.zn() * std::erf(x)) * std::sin(g * x);
301 values_(iat)(iq) = s.interpolate().integrate(0);
303 unit_cell_.comm().allgather(&values_(iat)(0), spl_q_.local_size(), spl_q_.global_offset());
304 values_(iat).interpolate();
308void Radial_integrals_rho_free_atom::generate()
310 PROFILE(
"sirius::Radial_integrals|rho_free_atom");
316 #pragma omp parallel for
321 for (
int ir = 0; ir < s.num_points(); ir++) {
322 s(ir) = atom_type.free_atom_density(ir);
324 values_(iat)(iq) = s.interpolate().integrate(2);
326 for (
int ir = 0; ir < s.num_points(); ir++) {
327 s(ir) = atom_type.free_atom_density(ir) * std::sin(g * atom_type.free_atom_radial_grid(ir));
329 values_(iat)(iq) = s.interpolate().integrate(1);
336template class Radial_integrals_atomic_wf<true>;
337template class Radial_integrals_atomic_wf<false>;
339template class Radial_integrals_aug<true>;
340template class Radial_integrals_aug<false>;
342template class Radial_integrals_rho_core_pseudo<true>;
343template class Radial_integrals_rho_core_pseudo<false>;
345template class Radial_integrals_beta<true>;
346template class Radial_integrals_beta<false>;
348template class Radial_integrals_vloc<true>;
349template class Radial_integrals_vloc<false>;
int num_points() const
Number of grid points.
void generate(std::function< Spline< double > const &(int, int)> fl__)
Generate radial integrals.
Radial integrals of the augmentation operator.
sddk::mdarray< Spline< double >, N > values_
Array with integrals.
Unit_cell const & unit_cell_
Unit cell.
splindex_block spl_q_
Split index of q-points.
Radial_grid< double > grid_q_
Linear grid of q-points on which the interpolation of radial integrals is done.
void generate()
Generate radial integrals on the q-grid.
int num_atom_types() const
Number of atom types.
Atom_type & atom_type(int id__)
Return atom type instance by id.
Multidimensional array with the column-major (Fortran) order.
Spherical Bessel functions up to lmax.
Spline< double > deriv_q(int l__)
Derivative of Bessel function with respect to q.
value_type local_size(block_id block_id__) const
Return local size of the split index for a given block.
int lmax(int lmmax__)
Get maximum orbital quantum number by the maximum lm index.
Namespace of the SIRIUS library.
strong_type< int, struct __rf_index_tag > rf_index
Radial function index.
Representation of various radial integrals.