Loading...
Searching...
No Matches
init.hpp
Go to the documentation of this file.
1#pragma once
2
3/**
4 * Preconditioner — abstract base class for SCF residual preconditioners.
5 *
6 * A preconditioner reshapes the density residual before it enters the mixing
7 * update, damping the long-wavelength charge-sloshing modes that make the
8 * self-consistent iteration converge slowly (or not at all) in metals and in
9 * large or inhomogeneous cells.
10 *
11 * The interface is an operator rather than a weight array because not every
12 * useful preconditioner is diagonal in G. Kerker is (one multiply per G), but
13 * a preconditioner built from a spatially varying screening length is diagonal
14 * in neither representation and has to be applied by solving a linear system.
15 * Concrete implementations live one per file in this directory.
16 */
17
18#include <string>
19#include <vector>
20
22
23namespace q3 {
24
25/// Abstract base class for all SCF residual preconditioners.
27 public:
28 virtual ~Preconditioner() = default;
29
30 [[nodiscard]] virtual std::string name() const = 0;
31
32 /**
33 * Apply the preconditioner to one G-space residual channel, in place.
34 *
35 * Callers pass the TOTAL charge channel only: the magnetization channel has
36 * no Coulomb kernel to screen, and damping its long-wavelength components
37 * would freeze slow moment relaxation. The G = 0 component must be left
38 * untouched — it is fixed by charge conservation, and the mixing metric
39 * excludes it for the same reason.
40 *
41 * @param residual_g residual in reciprocal space; overwritten with the
42 * preconditioned residual.
43 */
44 virtual void apply(std::vector<Complex>& residual_g) const = 0;
45
46 /**
47 * Supply the current real-space input density, summed over spin channels,
48 * before the next apply().
49 *
50 * Density-independent preconditioners (identity, Kerker) ignore it. One
51 * built from the local density recomputes its screening from it, which is
52 * why this is a separate call: the mixer knows when the density is current,
53 * and apply() may run more than once per SCF step.
54 */
55 virtual void update(const std::vector<Real>& /*density_real*/) {}
56};
57
58} // namespace q3
Abstract base class for all SCF residual preconditioners.
Definition init.hpp:26
virtual void update(const std::vector< Real > &)
Definition init.hpp:55
virtual void apply(std::vector< Complex > &residual_g) const =0
virtual std::string name() const =0
virtual ~Preconditioner()=default