127 int number_of_plane_waves,
128 const std::vector<int>& g_vector_indices,
129 const Crystal& crystal_structure,
133 const std::vector<std::vector<std::vector<Real>>>& atomic_wavefunction_table,
135 int number_of_q_points,
136 std::vector<std::vector<Complex>>& orbitals) {
138 Vector3D kpoint_crystal = kpoint_grid[kpoint_index].coordinates;
142 for (
int dimension = 0; dimension < 3; dimension++) {
143 kpoint_cartesian[dimension] = kpoint_crystal.
x * reciprocal_lattice[0][dimension] +
144 kpoint_crystal.
y * reciprocal_lattice[1][dimension] +
145 kpoint_crystal.
z * reciprocal_lattice[2][dimension];
148 int maximum_angular_momentum = 0;
149 for (
int species_index = 0; species_index < pseudopotential_set.
size(); species_index++) {
150 for (
const auto& atomic_wavefunction :
151 pseudopotential_set[species_index].wavefunctions_atomic) {
152 if (atomic_wavefunction.occupations >= 0.0) {
153 maximum_angular_momentum =
154 std::max(maximum_angular_momentum, atomic_wavefunction.angular_momentum);
158 int number_of_lm_components = (maximum_angular_momentum + 1) * (maximum_angular_momentum + 1);
160 std::vector<std::array<Real, 3>> gk_vectors(number_of_plane_waves);
161 std::vector<Real> q_plus_g_magnitude_squared(number_of_plane_waves);
162 std::vector<Real> q_plus_g_magnitude(number_of_plane_waves);
164 for (
int g_index = 0; g_index < number_of_plane_waves; g_index++) {
165 const auto& g_vector = planewave_basis.
g_vectors()[g_vector_indices[g_index]];
166 gk_vectors[g_index][0] = kpoint_cartesian.
x + g_vector.g_cart.x;
167 gk_vectors[g_index][1] = kpoint_cartesian.
y + g_vector.g_cart.y;
168 gk_vectors[g_index][2] = kpoint_cartesian.
z + g_vector.g_cart.z;
169 q_plus_g_magnitude_squared[g_index] = gk_vectors[g_index][0] * gk_vectors[g_index][0] +
170 gk_vectors[g_index][1] * gk_vectors[g_index][1] +
171 gk_vectors[g_index][2] * gk_vectors[g_index][2];
172 q_plus_g_magnitude[g_index] =
173 std::sqrt(q_plus_g_magnitude_squared[g_index]) * two_pi_over_lattice_parameter;
176 std::vector<std::vector<Real>> spherical_harmonics_values;
178 number_of_plane_waves,
180 q_plus_g_magnitude_squared,
181 spherical_harmonics_values);
183 int number_of_species =
static_cast<int>(pseudopotential_set.
size());
185 std::vector<std::vector<std::vector<Real>>> atomic_wavefunction_values(number_of_plane_waves);
186 for (
int g_index = 0; g_index < number_of_plane_waves; g_index++) {
187 atomic_wavefunction_values[g_index].resize(0);
188 for (
int type_index = 0; type_index < number_of_species; type_index++) {
189 int number_of_wavefunctions_for_type =
190 static_cast<int>(pseudopotential_set[type_index].wavefunctions_atomic.
size());
191 std::vector<Real> atomic_wavefunction_values_for_type(number_of_wavefunctions_for_type,
193 for (
int wavefunction_index = 0; wavefunction_index < number_of_wavefunctions_for_type;
194 wavefunction_index++) {
195 if (pseudopotential_set[type_index]
196 .wavefunctions_atomic[wavefunction_index]
199 atomic_wavefunction_values_for_type[wavefunction_index] =
201 atomic_wavefunction_table[type_index][wavefunction_index],
202 q_plus_g_magnitude[g_index],
206 atomic_wavefunction_values[g_index].push_back(
207 std::move(atomic_wavefunction_values_for_type));
212 orbitals.assign(number_of_atomic_orbitals,
213 std::vector<Complex>(number_of_plane_waves,
Complex(0.0, 0.0)));
215 int orbital_index = 0;
216 for (
int atom_index = 0; atom_index < crystal_structure.
number_of_atoms(); atom_index++) {
217 Vector3D atomic_position_cartesian =
220 const auto& pseudopotential = pseudopotential_set[type_index];
222 Real phase_argument = (kpoint_cartesian.
x * atomic_position_cartesian.
x +
223 kpoint_cartesian.
y * atomic_position_cartesian.
y +
224 kpoint_cartesian.
z * atomic_position_cartesian.
z) *
228 std::vector<Complex> structure_factor(number_of_plane_waves);
229 for (
int g_index = 0; g_index < number_of_plane_waves; g_index++) {
230 const auto& g_vector = planewave_basis.
g_vectors()[g_vector_indices[g_index]];
232 g_vector.g_cart.y * atomic_position_cartesian.
y +
233 g_vector.g_cart.z * atomic_position_cartesian.
z);
237 for (
int wavefunction_index = 0;
238 wavefunction_index < static_cast<int>(pseudopotential.wavefunctions_atomic.size());
239 wavefunction_index++) {
240 if (pseudopotential.wavefunctions_atomic[wavefunction_index].occupations < 0.0)
243 int angular_momentum =
244 pseudopotential.wavefunctions_atomic[wavefunction_index].angular_momentum;
246 Complex angular_momentum_phase;
247 switch (angular_momentum % 4) {
249 angular_momentum_phase =
Complex(1.0, 0.0);
252 angular_momentum_phase =
Complex(0.0, 1.0);
255 angular_momentum_phase =
Complex(-1.0, 0.0);
258 angular_momentum_phase =
Complex(0.0, -1.0);
262 for (
int magnetic_index = 0; magnetic_index < 2 * angular_momentum + 1;
264 int combined_lm_index = angular_momentum * angular_momentum + magnetic_index;
265 for (
int g_index = 0; g_index < number_of_plane_waves; g_index++) {
266 orbitals[orbital_index][g_index] =
267 angular_momentum_phase * structure_factor[g_index] *
269 spherical_harmonics_values[g_index][combined_lm_index] *
270 atomic_wavefunction_values[g_index][type_index][wavefunction_index],