Quantum 3xplorer (Q3)
An AI-native quantum simulation engine
Loading...
Searching...
No Matches
q3::LinearMixer Class Reference

#include <linear.hpp>

+ Inheritance diagram for q3::LinearMixer:

Public Member Functions

 LinearMixer (Real mixing_parameter=0.4)
 
void mix_in_reciprocal_space (std::vector< std::vector< Complex > > &rho_in_g, const std::vector< std::vector< Complex > > &rho_out_g, int number_of_spin_components) override
 
std::string name () const override
 
- Public Member Functions inherited from q3::ReciprocalSpaceMixer
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
 
 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 void reset ()
 

Additional Inherited Members

- Static Public Member Functions inherited from q3::ReciprocalSpaceMixer
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 inherited from q3::ReciprocalSpaceMixer
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 inherited from q3::ReciprocalSpaceMixer
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_
 

Detailed Description

Simple linear density mixer operating in G-space with optional Kerker preconditioning.

Convergence is guaranteed for sufficiently small alpha, unlike Broyden which can diverge for difficult metallic systems.

Not to be confused with mixing_mode='plain' in a Quantum ESPRESSO input: there, 'plain' only turns the preconditioner off and the Broyden history still runs, which is why io/input/parser/qe.hpp maps it to this code's Broyden mixer rather than to this class.

Definition at line 37 of file linear.hpp.

Constructor & Destructor Documentation

◆ LinearMixer()

q3::LinearMixer::LinearMixer ( Real  mixing_parameter = 0.4)
inlineexplicit

Definition at line 39 of file linear.hpp.

Member Function Documentation

◆ mix_in_reciprocal_space()

void q3::LinearMixer::mix_in_reciprocal_space ( std::vector< std::vector< Complex > > &  rho_in_g,
const std::vector< std::vector< Complex > > &  rho_out_g,
int  number_of_spin_components 
)
inlineoverridevirtual

Perform one linear mixing step in G-space.

ρ_new = ρ_in + α · K(G) · (ρ_out - ρ_in)

where K is the configured residual preconditioner (Kerker or local-TF if enabled, the identity otherwise).

Compute last_residual_norm_ BEFORE mixing using the pre-mix residual, in the same shared two-channel metric Broyden reports – see ReciprocalSpaceMixer::compute_metric_dot_product().

Apply linear mixing: ρ_new = ρ_in + α · K(G) · (ρ_out - ρ_in) K(G) = G²/(G²+q0²) for Kerker, 1 otherwise. Only mix smooth G here. Hard G above smooth_g_vector_count are mixed separately, by the hard-G loop in ReciprocalSpaceMixer::mix().

Charge channel: G=0 is fixed by charge conservation, and the preconditioner screens the Coulomb response. Magnetization channel (spin 1 in the (total, m) representation): the moment is not conserved, so its G=0 component must be mixed, and no screening applies (no Coulomb kernel for m).

The preconditioner is an operator, so the residual is formed first and preconditioned as a whole rather than scaled per G on the fly. It is built over the full G range even though only the smooth range is mixed here – a non-diagonal preconditioner couples G components, and truncating its input to the smooth range would solve a different problem. For a diagonal preconditioner this is exactly the previous per-G multiply.

Implements q3::ReciprocalSpaceMixer.

Definition at line 49 of file linear.hpp.

References q3::ReciprocalSpaceMixer::compute_metric_dot_product(), q3::ReciprocalSpaceMixer::first_nonzero_g_index_, q3::Mixer::last_residual_norm_, q3::Mixer::mixing_parameter_, q3::ReciprocalSpaceMixer::number_of_smooth_g_vectors_, and q3::ReciprocalSpaceMixer::preconditioner_.

◆ name()

std::string q3::LinearMixer::name ( ) const
inlineoverridevirtual

Implements q3::Mixer.

Definition at line 114 of file linear.hpp.


The documentation for this class was generated from the following file: