SIRIUS 7.5.0
Electronic structure library and applications
beta_projectors.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 beta_projectors.hpp
21 *
22 * \brief Contains declaration and implementation of sirius::Beta_projectors class.
23 */
24
25#ifndef __BETA_PROJECTORS_HPP__
26#define __BETA_PROJECTORS_HPP__
27
29
30namespace sirius {
31
32/// Stores <G+k | beta> expansion
33template <typename T>
35{
36 protected:
37 /// Generate plane-wave coefficients for beta-projectors of atom types.
39 {
40 PROFILE("sirius::Beta_projectors::generate_pw_coefs_t");
41 if (!this->num_beta_t()) {
42 return;
43 }
44
45 auto& uc = this->ctx_.unit_cell();
46
47 std::vector<int> offset_t(uc.num_atom_types());
48 std::generate(offset_t.begin(), offset_t.end(),
49 [n = 0, iat = 0, &uc] () mutable
50 {
51 int offs = n;
52 n += uc.atom_type(iat++).mt_basis_size();
53 return offs;
54 });
55
56 auto& comm = this->gkvec_.comm();
57
58 auto& beta_radial_integrals = *this->ctx_.ri().beta_;
59
60 std::vector<std::complex<double>> z(uc.lmax() + 1);
61 for (int l = 0; l <= uc.lmax(); l++) {
62 z[l] = std::pow(std::complex<double>(0, -1), l) * fourpi / std::sqrt(uc.omega());
63 }
64
65 /* compute <G+k|beta> */
66 #pragma omp parallel for
67 for (int igkloc = 0; igkloc < this->num_gkvec_loc(); igkloc++) {
68 /* vs = {r, theta, phi} */
69 auto vs = r3::spherical_coordinates(this->gkvec_.template gkvec_cart<index_domain_t::local>(igkloc));
70 /* compute real spherical harmonics for G+k vector */
71 std::vector<double> gkvec_rlm(sf::lmmax(uc.lmax()));
72 sf::spherical_harmonics(uc.lmax(), vs[1], vs[2], &gkvec_rlm[0]);
73 for (int iat = 0; iat < uc.num_atom_types(); iat++) {
74 auto& atom_type = uc.atom_type(iat);
75 /* get all values of radial integrals */
76 auto ri_val = beta_radial_integrals.values(iat, vs[0]);
77 for (int xi = 0; xi < atom_type.mt_basis_size(); xi++) {
78 int l = atom_type.indexb(xi).am.l();
79 int lm = atom_type.indexb(xi).lm;
80 int idxrf = atom_type.indexb(xi).idxrf;
81
82 this->pw_coeffs_t_(igkloc, offset_t[atom_type.id()] + xi, 0) =
83 static_cast<std::complex<T>>(z[l] * gkvec_rlm[lm] * ri_val(idxrf));
84 }
85 }
86 }
87
88 if (env::print_checksum()) {
89 auto c1 = this->pw_coeffs_t_.checksum();
90 comm.allreduce(&c1, 1);
91 if (comm.rank() == 0) {
92 print_checksum("beta_pw_coeffs_t", c1, std::cout);
93 }
94 }
95 }
96
97 public:
98 Beta_projectors(Simulation_context& ctx__, fft::Gvec const& gkvec__)
99 : Beta_projectors_base<T>(ctx__, gkvec__, 1)
100 {
101 PROFILE("sirius::Beta_projectors");
102 /* generate phase-factor independent projectors for atom types */
104 if (!this->num_beta_t()) {
105 return;
106 }
107
108 if (this->ctx_.processing_unit() == sddk::device_t::GPU) {
109 this->reallocate_pw_coeffs_t_on_gpu_ = false;
110 // TODO remove is done in `Beta_projector_generator`
111 this->pw_coeffs_t_.allocate(sddk::memory_t::device).copy_to(sddk::memory_t::device);
112 }
113 int nbeta{0};
114 for (int iat = 0; iat < ctx__.unit_cell().num_atom_types(); iat++) {
115 nbeta += ctx__.unit_cell().atom_type(iat).num_atoms() * ctx__.unit_cell().atom_type(iat).mt_basis_size();
116 }
117
118 // TODO: can be improved... nlcglib might ask for beta coefficients on host,
119 // create them such that they are there in any case
120 this->beta_pw_all_atoms_ =
121 sddk::matrix<std::complex<T>>(this->num_gkvec_loc(), nbeta);
122 for (int ichunk = 0; ichunk < this->num_chunks(); ++ichunk) {
123 this->pw_coeffs_a_ =
124 sddk::matrix<std::complex<T>>(&this->beta_pw_all_atoms_(0, this->beta_chunks_[ichunk].offset_),
125 this->num_gkvec_loc(), this->beta_chunks_[ichunk].num_beta_);
126 local::beta_projectors_generate_cpu(this->pw_coeffs_a_, this->pw_coeffs_t_, ichunk, /*j*/ 0,
127 this->beta_chunks_[ichunk], ctx__, gkvec__);
128 }
129 }
130};
131
132} // namespace sirius
133
134#endif
Contains declaration and implementation of sirius::Beta_projectors_base class.
Base class for beta-projectors, gradient of beta-projectors and strain derivatives of beta-projectors...
fft::Gvec const & gkvec_
List of G+k vectors.
sddk::matrix< std::complex< T > > pw_coeffs_a_
Set of beta PW coefficients for a chunk of atoms.
sddk::mdarray< std::complex< T >, 3 > pw_coeffs_t_
Phase-factor independent coefficients of |beta> functions for atom types.
sddk::matrix< std::complex< T > > beta_pw_all_atoms_
Set of beta PW coefficients for all atoms.
Stores <G+k | beta> expansion.
void generate_pw_coefs_t()
Generate plane-wave coefficients for beta-projectors of atom types.
Simulation context is a set of parameters and objects describing a single simulation.
A set of G-vectors for FFTs and G+k basis functions.
Definition: gvec.hpp:130
void allreduce(T *buffer__, int count__) const
Perform the in-place (the output buffer is used as the input buffer) all-to-all reduction.
int rank() const
Rank of MPI process inside communicator.
mdarray< T, N > & allocate(memory_t memory__)
Allocate memory for array.
Definition: memory.hpp:1057
T checksum(size_t idx0__, size_t size__) const
Compute checksum.
Definition: memory.hpp:1262
auto spherical_coordinates(vector< double > vc)
Transform Cartesian coordinates [x,y,z] to spherical coordinates [r,theta,phi].
Definition: r3.hpp:590
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
void spherical_harmonics(int lmax, double theta, double phi, std::complex< double > *ylm)
Optimized implementation of complex spherical harmonics.
Definition: specfunc.hpp:298
Namespace of the SIRIUS library.
Definition: sirius.f90:5
const double fourpi
Definition: constants.hpp:48