41 void mix(
const std::vector<std::vector<Real>>& input_density,
42 std::vector<std::vector<Real>>& output_density,
43 int number_of_spin_components)
override {
55 std::vector<std::vector<Complex>> input_density_g(number_of_spin_components);
56 std::vector<std::vector<Complex>> output_density_g(number_of_spin_components);
57 for (
int spin_index = 0; spin_index < number_of_spin_components; ++spin_index) {
70 if (number_of_spin_components == 2) {
86 for (
int spin_index = 0; spin_index < number_of_spin_components; ++spin_index) {
87 int number_of_g_vectors =
static_cast<int>(input_density_g[spin_index].size());
90 input_density_g[spin_index][g_index] +=
92 input_density_g[spin_index][g_index]);
97 if (number_of_spin_components == 2) {
101 for (
int spin_index = 0; spin_index < number_of_spin_components; ++spin_index) {
102 to_real_space_(input_density_g[spin_index], output_density[spin_index]);
107 static std::vector<Real>
109 int number_of_spin_components) {
110 std::vector<Real> total = density_real[0];
111 for (
int spin_index = 1; spin_index < number_of_spin_components; ++spin_index) {
112 for (std::size_t index = 0; index < total.size(); ++index) {
113 total[index] += density_real[spin_index][index];
122 for (std::size_t g_index = 0; g_index < density_g[0].size(); ++g_index) {
123 Complex up = density_g[0][g_index];
124 Complex down = density_g[1][g_index];
125 density_g[0][g_index] = up + down;
126 density_g[1][g_index] = up - down;
133 for (std::size_t g_index = 0; g_index < density_g[0].size(); ++g_index) {
134 Complex total = density_g[0][g_index];
135 Complex magnetization = density_g[1][g_index];
136 density_g[0][g_index] = 0.5 * (total + magnetization);
137 density_g[1][g_index] = 0.5 * (total - magnetization);
148 const std::vector<std::vector<Complex>>& output_density_g,
149 int number_of_spin_components) = 0;
169 const std::vector<std::vector<Complex>>& rho_b,
170 int number_of_spin_components,
171 int g_vector_count = -1)
const {
172 int g_count = (g_vector_count >= 0) ? g_vector_count :
static_cast<int>(rho_a[0].size());
180 Real charge_result = 0.0;
183 std::real(std::conj(rho_a[0][g_index]) * rho_b[0][g_index]);
185 result += charge_result * gamma_factor;
191 for (
int spin_index = 1; spin_index < number_of_spin_components; spin_index++) {
192 for (
int g_index = 0; g_index < g_count; g_index++) {
196 std::real(std::conj(rho_a[spin_index][g_index]) * rho_b[spin_index][g_index]);
204 std::function<void(
const std::vector<Complex>&, std::vector<Real>&)>
to_real_space_;
Abstract base class for all charge density mixers.
Mixer(Real mixing_parameter, int history_depth)
std::vector< Real > charge_metric_weights_
static void convert_up_down_to_total_magnetization(std::vector< std::vector< Complex > > &density_g)
In-place (ρ↑, ρ↓) → (ρ↑+ρ↓, ρ↑−ρ↓).
void initialize(const MixerEnvironment &environment) override
Supply the representation context the mixer needs before the first mix().
static std::vector< Real > sum_over_spin_channels(const std::vector< std::vector< Real > > &density_real, int number_of_spin_components)
Total real-space density ρ↑+ρ↓ (a copy of channel 0 when unpolarized).
std::shared_ptr< Preconditioner > preconditioner_
static void convert_total_magnetization_to_up_down(std::vector< std::vector< Complex > > &density_g)
In-place (ρ↑+ρ↓, ρ↑−ρ↓) → (ρ↑, ρ↓).
Real magnetization_metric_weight_
int number_of_smooth_g_vectors_
std::function< void(const std::vector< Real > &, std::vector< Complex > &)> to_reciprocal_space_
virtual void mix_in_reciprocal_space(std::vector< std::vector< Complex > > &input_density_g, const std::vector< std::vector< Complex > > &output_density_g, int number_of_spin_components)=0
Real compute_metric_dot_product(const std::vector< std::vector< Complex > > &rho_a, const std::vector< std::vector< Complex > > &rho_b, int number_of_spin_components, int g_vector_count=-1) const
void mix(const std::vector< std::vector< Real > > &input_density, std::vector< std::vector< Real > > &output_density, int number_of_spin_components) override
int first_nonzero_g_index_
std::function< void(const std::vector< Complex > &, std::vector< Real > &)> to_real_space_
std::complex< double > Complex
int first_nonzero_g_index
Real magnetization_metric_weight
std::function< void(const std::vector< Complex > &, std::vector< Real > &)> to_real_space
int number_of_smooth_g_vectors
std::shared_ptr< Preconditioner > preconditioner
std::function< void(const std::vector< Real > &, std::vector< Complex > &)> to_reciprocal_space
std::vector< Real > charge_metric_weights