61 int number_of_channels = expansion.
size();
63 int mesh_size = pseudopotential.
mesh_size;
66 std::vector<Real> d_matrix(
static_cast<size_t>(number_of_channels) * number_of_channels, 0.0);
68 std::vector<Real> integrand(mesh_size);
69 for (
int first = 0; first < number_of_channels; first++) {
70 for (
int second = 0; second < number_of_channels; second++) {
73 int lm_first = expansion.
lm_index[first];
74 int lm_second = expansion.
lm_index[second];
75 int pair_index = radial_first * number_of_radial + radial_second;
77 const auto& all_electron_first =
79 const auto& all_electron_second =
81 const auto& pseudo_first =
83 const auto& pseudo_second =
86 Real accumulated = 0.0;
94 const bool gradient_corrected =
energy.all_electron.has_gradient_correction();
95 std::vector<Real> all_electron_channel;
96 std::vector<Real> pseudo_channel;
97 std::vector<Real> all_electron_channel_derivative;
98 std::vector<Real> pseudo_channel_derivative;
100 for (
int lm = 0; lm < number_of_lm; lm++) {
106 const std::vector<Real>* augmentation =
nullptr;
114 const auto& candidate =
117 if (!candidate.empty())
118 augmentation = &candidate;
122 for (
int point = 0; point < mesh_size; point++) {
123 integrand[point] = angular * all_electron_first[point] *
124 all_electron_second[point] *
125 energy.all_electron.potential_lm[lm][point];
129 accumulated += cumulative[mesh_size - 1];
131 if (gradient_corrected) {
132 all_electron_channel.assign(mesh_size, 0.0);
133 for (
int point = 0; point < mesh_size; point++) {
135 all_electron_channel[point] = angular * all_electron_first[point] *
136 all_electron_second[point] /
141 for (
int point = 0; point < mesh_size; point++) {
144 radius * radius * all_electron_channel_derivative[point] *
145 energy.all_electron.gradient_radial_weight_lm[lm][point] +
146 all_electron_channel[point] *
147 energy.all_electron.gradient_angular_weight_lm[lm][point];
151 accumulated += cumulative[mesh_size - 1];
155 for (
int point = 0; point < mesh_size; point++) {
156 Real pseudo_value = pseudo_first[point] * pseudo_second[point];
157 if (augmentation !=
nullptr)
158 pseudo_value += (*augmentation)[point];
160 angular * pseudo_value *
energy.pseudo.potential_lm[lm][point];
164 accumulated -= cumulative[mesh_size - 1];
166 if (gradient_corrected) {
167 pseudo_channel.assign(mesh_size, 0.0);
168 for (
int point = 0; point < mesh_size; point++) {
170 Real pseudo_value = pseudo_first[point] * pseudo_second[point];
171 if (augmentation !=
nullptr)
172 pseudo_value += (*augmentation)[point];
173 pseudo_channel[point] = angular * pseudo_value / (radius * radius);
177 for (
int point = 0; point < mesh_size; point++) {
179 integrand[point] = radius * radius * pseudo_channel_derivative[point] *
180 energy.pseudo.gradient_radial_weight_lm[lm][point] +
181 pseudo_channel[point] *
182 energy.pseudo.gradient_angular_weight_lm[lm][point];
186 accumulated -= cumulative[mesh_size - 1];
189 d_matrix[
static_cast<size_t>(first) * number_of_channels + second] = accumulated;