SIRIUS 7.5.0
Electronic structure library and applications
beta_projectors_strain_deriv.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_strain_deriv.hpp
21 *
22 * \brief Contains declaration and implementation of sirius::Beta_projectors_strain_deriv class.
23 */
24
25#ifndef __BETA_PROJECTORS_STRAIN_DERIV_HPP__
26#define __BETA_PROJECTORS_STRAIN_DERIV_HPP__
27
29
30namespace sirius {
31
32template <typename T>
34{
35 private:
36
37 void generate_pw_coefs_t()
38 {
39 PROFILE("sirius::Beta_projectors_strain_deriv::generate_pw_coefs_t");
40
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& beta_ri0 = *this->ctx_.ri().beta_;
57 auto& beta_ri1 = *this->ctx_.ri().beta_djl_;
58
59 int lmax = uc.lmax();
60 int lmmax = sf::lmmax(lmax);
61
62 sddk::mdarray<double, 2> rlm_g(lmmax, this->num_gkvec_loc());
63 sddk::mdarray<double, 3> rlm_dg(lmmax, 3, this->num_gkvec_loc());
64
65 /* array of real spherical harmonics and derivatives for each G-vector */
66 #pragma omp parallel for schedule(static)
67 for (int igkloc = 0; igkloc < this->num_gkvec_loc(); igkloc++) {
68 auto gvc = this->gkvec_.template gkvec_cart<index_domain_t::local>(igkloc);
69 auto rtp = r3::spherical_coordinates(gvc);
70
71 double theta = rtp[1];
72 double phi = rtp[2];
73
74 sf::spherical_harmonics(lmax, theta, phi, &rlm_g(0, igkloc));
75 sddk::mdarray<double, 2> rlm_dg_tmp(&rlm_dg(0, 0, igkloc), lmmax, 3);
76 sf::dRlm_dr(lmax, gvc, rlm_dg_tmp);
77 }
78
79 this->pw_coeffs_t_.zero(sddk::memory_t::host);
80
81 /* compute d <G+k|beta> / d epsilon_{mu, nu} */
82 #pragma omp parallel for schedule(static)
83 for (int igkloc = 0; igkloc < this->num_gkvec_loc(); igkloc++) {
84 auto gvc = this->gkvec_.template gkvec_cart<index_domain_t::local>(igkloc);
85 /* vs = {r, theta, phi} */
86 auto gvs = r3::spherical_coordinates(gvc);
87
88 auto inv_len = (gvs[0] < 1e-10) ? 0 : 1.0 / gvs[0];
89
90 for (int iat = 0; iat < uc.num_atom_types(); iat++) {
91 auto& atom_type = uc.atom_type(iat);
92
93 auto ri0 = beta_ri0.values(iat, gvs[0]);
94 auto ri1 = beta_ri1.values(iat, gvs[0]);
95
96 for (int nu = 0; nu < 3; nu++) {
97 for (int mu = 0; mu < 3; mu++) {
98 double p = (mu == nu) ? 0.5 : 0;
99
100 for (int xi = 0; xi < atom_type.mt_basis_size(); xi++) {
101 int l = atom_type.indexb(xi).am.l();
102 int lm = atom_type.indexb(xi).lm;
103 int idxrf = atom_type.indexb(xi).idxrf;
104
105 auto z = std::pow(std::complex<double>(0, -1), l) * fourpi /
106 std::sqrt(uc.omega());
107
108 auto d1 = ri0(idxrf) * (-gvc[mu] * rlm_dg(lm, nu, igkloc) - p * rlm_g(lm, igkloc));
109
110 auto d2 = ri1(idxrf) * rlm_g(lm, igkloc) * (-gvc[mu] * gvc[nu] * inv_len);
111
112 this->pw_coeffs_t_(igkloc, offset_t[atom_type.id()] + xi, mu + nu * 3) =
113 static_cast<std::complex<T>>(z * (d1 + d2));
114 }
115 }
116 }
117 }
118 }
119 }
120
121 public:
123 : Beta_projectors_base<T>(ctx__, gkvec__, 9)
124 {
125 generate_pw_coefs_t();
126 }
127};
128
129} // namespace sirius
130
131#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::mdarray< std::complex< T >, 3 > pw_coeffs_t_
Phase-factor independent coefficients of |beta> functions for 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 zero(memory_t mem__, size_t idx0__, size_t n__)
Zero n elements starting from idx0.
Definition: memory.hpp:1316
auto spherical_coordinates(vector< double > vc)
Transform Cartesian coordinates [x,y,z] to spherical coordinates [r,theta,phi].
Definition: r3.hpp:590
int lmax(int lmmax__)
Get maximum orbital quantum number by the maximum lm index.
Definition: specfunc.hpp:56
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 dRlm_dr(int lmax__, r3::vector< double > &r__, sddk::mdarray< double, 2 > &data__, bool divide_by_r__=true)
Compute the derivatives of real spherical harmonics over the components of cartesian vector.
Definition: specfunc.hpp:512
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