Loading...
Searching...
No Matches
hartree.hpp
Go to the documentation of this file.
1#pragma once
2
3/**
4 * Hartree stress tensor contribution.
5 *
6 * Computes the Hartree (electrostatic) contribution to the stress tensor
7 * from the charge density in reciprocal space.
8 *
9 * This is a purely planewave contribution, independent of pseudopotential type.
10 */
11
12#include <cmath>
13
20
21namespace q3 {
22
24 public:
25 HartreeStressTensorCalculator(const Crystal& crystal_structure,
26 const PlanewaveBasis& planewave_basis,
29 : crystal_structure_(crystal_structure)
30 , planewave_basis_(planewave_basis)
31 , scf_state_(scf_state)
32 , result_(result) {}
33
34 void compute() {
35 Real hartree_energy = scf_state_.energies().hartree_energy;
36 const auto& charge_density_g = scf_state_.charge_density_g;
37 Real reciprocal_space_multiplicity = planewave_basis_.is_gamma_only() ? 2.0 : 1.0;
38 Real stress_xx = 0, stress_yx = 0, stress_yy = 0, stress_zx = 0, stress_zy = 0,
39 stress_zz = 0;
40
41 for (int g_vector_index = planewave_basis_.first_nonzero_g_index();
42 g_vector_index < planewave_basis_.number_of_g_vectors();
43 g_vector_index++) {
44 const auto& g_vector = planewave_basis_.g_vectors()[g_vector_index];
45 Real g_vector_squared = g_vector.magnitude_squared;
46 if (g_vector_squared < math::tolerances::numerical_zero_threshold)
47 continue;
48 Real hartree_stress_term = reciprocal_space_multiplicity *
49 std::norm(charge_density_g[g_vector_index]) /
50 g_vector_squared;
51 stress_xx += hartree_stress_term * 2.0 * g_vector.g_cart.x * g_vector.g_cart.x /
52 g_vector_squared;
53 stress_yx += hartree_stress_term * 2.0 * g_vector.g_cart.y * g_vector.g_cart.x /
54 g_vector_squared;
55 stress_yy += hartree_stress_term * 2.0 * g_vector.g_cart.y * g_vector.g_cart.y /
56 g_vector_squared;
57 stress_zx += hartree_stress_term * 2.0 * g_vector.g_cart.z * g_vector.g_cart.x /
58 g_vector_squared;
59 stress_zy += hartree_stress_term * 2.0 * g_vector.g_cart.z * g_vector.g_cart.y /
60 g_vector_squared;
61 stress_zz += hartree_stress_term * 2.0 * g_vector.g_cart.z * g_vector.g_cart.z /
62 g_vector_squared;
63 }
65 crystal_structure_.two_pi_over_lattice_parameter_squared();
66 Real cell_volume = crystal_structure_.cell_volume();
67 result_.hartree[0][0] = prefactor * stress_xx - hartree_energy / cell_volume;
68 result_.hartree[1][0] = prefactor * stress_yx;
69 result_.hartree[1][1] = prefactor * stress_yy - hartree_energy / cell_volume;
70 result_.hartree[2][0] = prefactor * stress_zx;
71 result_.hartree[2][1] = prefactor * stress_zy;
72 result_.hartree[2][2] = prefactor * stress_zz - hartree_energy / cell_volume;
73 for (int direction_a = 0; direction_a < 3; direction_a++) {
74 for (int direction_b = 0; direction_b < 3; direction_b++) {
75 result_.hartree[direction_a][direction_b] =
76 -result_.hartree[direction_a][direction_b];
77 }
78 }
79 result_.hartree[0][1] = result_.hartree[1][0];
80 result_.hartree[0][2] = result_.hartree[2][0];
81 result_.hartree[1][2] = result_.hartree[2][1];
82 }
83
84 private:
85 const Crystal& crystal_structure_;
86 const PlanewaveBasis& planewave_basis_;
89};
90
91} // namespace q3
Real two_pi_over_lattice_parameter_squared() const
Definition crystal.hpp:199
Real cell_volume() const
Definition crystal.hpp:193
HartreeStressTensorCalculator(const Crystal &crystal_structure, const PlanewaveBasis &planewave_basis, const NormConservingPlanewaveKohnShamSCFState &scf_state, StressTensorContributions &result)
Definition hartree.hpp:25
int number_of_g_vectors() const
Definition init.hpp:145
const std::vector< GVector > & g_vectors() const
Definition init.hpp:148
int first_nonzero_g_index() const
Definition init.hpp:151
bool is_gamma_only() const
Definition init.hpp:157
constexpr Real electron_charge_squared_rydberg
Definition constants.hpp:32
constexpr Real four_pi
Definition constants.hpp:26
constexpr double numerical_zero_threshold
double Real
const NormConservingPlanewaveKohnShamEnergies & energies() const override
Return the converged energy breakdown (covariant return).
Definition init.hpp:87
std::vector< Complex > charge_density_g
Definition init.hpp:36
Per-contribution stress tensor breakdown (kbar after conversion).