#include <init.hpp>
Inheritance diagram for q3::ReciprocalSpaceMixer:Public Member Functions | |
| void | initialize (const MixerEnvironment &environment) override |
| Supply the representation context the mixer needs before the first mix(). | |
| void | mix (const std::vector< std::vector< Real > > &input_density, std::vector< std::vector< Real > > &output_density, int number_of_spin_components) override |
| 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 |
| Mixer (Real mixing_parameter, int history_depth) | |
Public Member Functions inherited from q3::Mixer | |
| Mixer (Real mixing_parameter, int history_depth) | |
| virtual | ~Mixer ()=default |
| int | history_depth () const |
| Real | last_residual_norm () const |
| Real | mixing_parameter () const |
| virtual std::string | name () const =0 |
| virtual void | reset () |
Static Public Member Functions | |
| static void | convert_total_magnetization_to_up_down (std::vector< std::vector< Complex > > &density_g) |
| In-place (ρ↑+ρ↓, ρ↑−ρ↓) → (ρ↑, ρ↓). | |
| static void | convert_up_down_to_total_magnetization (std::vector< std::vector< Complex > > &density_g) |
| In-place (ρ↑, ρ↓) → (ρ↑+ρ↓, ρ↑−ρ↓). | |
| 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). | |
Protected Member Functions | |
| 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 |
Protected Attributes | |
| std::vector< Real > | charge_metric_weights_ |
| int | first_nonzero_g_index_ {0} |
| bool | is_gamma_only_ {false} |
| Real | magnetization_metric_weight_ {0.0} |
| int | number_of_smooth_g_vectors_ {0} |
| std::shared_ptr< Preconditioner > | preconditioner_ |
| std::function< void(const std::vector< Complex > &, std::vector< Real > &)> | to_real_space_ |
| std::function< void(const std::vector< Real > &, std::vector< Complex > &)> | to_reciprocal_space_ |
Protected Attributes inherited from q3::Mixer | |
| int | history_depth_ |
| Real | last_residual_norm_ {-1.0} |
| Real | mixing_parameter_ |
Mixer operating on G-space charge density vectors with a precomputed metric.
The unified real-space mix() transforms densities to reciprocal space, defers to the concrete mix_in_reciprocal_space() update, and transforms back, so the caller never has to know the mixer works in G-space.
|
inlineprotected |
Weighted inner product ⟨ρ_a|ρ_b⟩ in the two-channel mixing metric – the same metric the SCF reports its convergence estimate in, so that a conv_thr value carried in from a plane-wave input means the same thing here as there:
channel 0 (total charge): Σ_{G≠0} w_charge(G) ρ_a*(G) ρ_b(G), w_charge = Hartree kernel ∝ 1/G² channel 1 (magnetization): Σ_{all G, incl. G=0} w_m ρ_a*(G) ρ_b(G), w_m = flat metric (no Coulomb kernel)
On gamma-only half-sphere grids every G≠0 term is doubled (ρ(-G) = ρ*(G)); the G=0 magnetization term is stored once and is not doubled.
| g_vector_count | Limit the G range (e.g. smooth-only mixing); pass a negative value to use the full vectors. |
Total charge channel: Hartree 1/G² metric, G=0 excluded (fixed by charge conservation, and the kernel diverges there).
Magnetization channels: flat metric including G=0 (the total moment is not conserved and must contribute to the metric).
Definition at line 168 of file init.hpp.
References charge_metric_weights_, first_nonzero_g_index_, is_gamma_only_, and magnetization_metric_weight_.
Referenced by q3::BroydenMixer::mix_in_reciprocal_space(), and q3::LinearMixer::mix_in_reciprocal_space().
|
inlinestatic |
|
inlinestatic |
|
inlineoverridevirtual |
Supply the representation context the mixer needs before the first mix().
Reimplemented from q3::Mixer.
Definition at line 30 of file init.hpp.
References q3::MixerEnvironment::charge_metric_weights, charge_metric_weights_, q3::MixerEnvironment::first_nonzero_g_index, first_nonzero_g_index_, q3::MixerEnvironment::is_gamma_only, is_gamma_only_, q3::MixerEnvironment::magnetization_metric_weight, magnetization_metric_weight_, q3::MixerEnvironment::number_of_smooth_g_vectors, number_of_smooth_g_vectors_, q3::MixerEnvironment::preconditioner, preconditioner_, q3::MixerEnvironment::to_real_space, to_real_space_, q3::MixerEnvironment::to_reciprocal_space, and to_reciprocal_space_.
|
inlineoverridevirtual |
Mix one self-consistent field step using real-space densities.
| input_density | density used to build the potential (rho_in), per spin. |
| output_density | density from the bands (rho_out) on entry; overwritten with the mixed next-iteration density on exit, per spin. |
| number_of_spin_components | number of spin channels. |
Each mixer performs whatever internal transforms it needs (e.g. FFT to reciprocal space) so callers never branch on the mixer's space.
A density-dependent preconditioner needs the TOTAL real-space density, and it needs it here: mix() receives (ρ↑, ρ↓), and the rotation to (total, magnetization) happens further down in G-space, so the sum over spin channels has to be done explicitly before the transforms.
Spin-polarized densities are mixed in the (total, magnetization) representation, the one that diagonalizes the mixing metric: channel 0 = ρ↑+ρ↓ carries the whole Coulomb response, so it gets the 1/G² metric and Kerker preconditioning; channel 1 = ρ↑−ρ↓ has no Coulomb kernel, so it gets the flat metric and no preconditioning. The per-channel metric code in the concrete mixers assumes this layout.
For dual-grid (ultrasoft/PAW) calculations, the hard G-vectors (above the smooth cutoff) carry the augmentation charges. They sit outside the Broyden subspace, so they need an update of their own; plain linear mixing at the configured mixing_beta is the cheapest stable one. Q3 was replacing them at 100% (beta=1.0), which caused augmentation oscillations and Broyden divergence. Fix: linear-mix hard G with the same mixing_parameter_ used for the smooth region.
Implements q3::Mixer.
Definition at line 41 of file init.hpp.
References convert_total_magnetization_to_up_down(), convert_up_down_to_total_magnetization(), mix_in_reciprocal_space(), q3::Mixer::mixing_parameter_, number_of_smooth_g_vectors_, preconditioner_, sum_over_spin_channels(), to_real_space_, and to_reciprocal_space_.
|
pure virtual |
Perform one mixing step in G-space.
| input_density_g | input density in G-space (modified in-place with the mixed result). |
| output_density_g | output density in G-space. |
| number_of_spin_components | number of spin components. |
Implemented in q3::BroydenMixer, and q3::LinearMixer.
Referenced by mix().
|
inline |
|
protected |
Definition at line 205 of file init.hpp.
Referenced by compute_metric_dot_product(), and initialize().
|
protected |
Definition at line 208 of file init.hpp.
Referenced by compute_metric_dot_product(), initialize(), and q3::LinearMixer::mix_in_reciprocal_space().
|
protected |
Definition at line 209 of file init.hpp.
Referenced by compute_metric_dot_product(), and initialize().
|
protected |
Definition at line 207 of file init.hpp.
Referenced by compute_metric_dot_product(), and initialize().
|
protected |
Definition at line 210 of file init.hpp.
Referenced by initialize(), mix(), q3::BroydenMixer::mix_in_reciprocal_space(), and q3::LinearMixer::mix_in_reciprocal_space().
|
protected |
Definition at line 206 of file init.hpp.
Referenced by initialize(), mix(), q3::BroydenMixer::mix_in_reciprocal_space(), and q3::LinearMixer::mix_in_reciprocal_space().
|
protected |
Definition at line 204 of file init.hpp.
Referenced by initialize(), and mix().
|
protected |
Definition at line 203 of file init.hpp.
Referenced by initialize(), and mix().