Loading...
Searching...
No Matches
factory.hpp
Go to the documentation of this file.
1#pragma once
2
3/**
4 * PreconditionerFactory — creates SCF residual preconditioners by name.
5 *
6 * Supported names:
7 * - "none" identity; no preconditioning.
8 * - "kerker" diagonal G²/(G²+q0²) filter (average Thomas-Fermi screening).
9 * - "local-tf" Thomas-Fermi screening from the local density, solved by
10 * conjugate gradients.
11 *
12 * Mirrors MixerFactory: an unknown name throws rather than silently selecting a
13 * default, so a typo fails loudly instead of turning preconditioning off.
14 */
15
16#include <functional>
17#include <memory>
18#include <stdexcept>
19#include <string>
20#include <utility>
21#include <vector>
22
27
28namespace q3 {
29
30/// Everything any preconditioner needs from the surrounding representation.
32 std::vector<Real> g_squared; ///< |G|² per G-vector, in bohr⁻².
33 Real q0_squared = 1.0; ///< Screening wavevector squared / vacuum floor, in bohr⁻².
35 std::function<void(const std::vector<Real>&, std::vector<Complex>&)> to_reciprocal_space;
36 std::function<void(const std::vector<Complex>&, std::vector<Real>&)> to_real_space;
37 /// Sums real-space integrals over the ranks sharing this pool's grid.
38 std::function<void(std::vector<Real>&)> global_reduce;
39};
40
41namespace PreconditionerFactory {
42
43/// The names create() accepts, for validation and error messages.
44inline bool is_supported(const std::string& name) {
45 return name == "none" || name == "kerker" || name == "local-tf";
46}
47
48/// Create a residual preconditioner by name.
49inline std::unique_ptr<Preconditioner> create(const std::string& name,
50 const PreconditionerEnvironment& environment) {
51 if (name == "none") {
52 return std::make_unique<NoPreconditioner>();
53 }
54 if (name == "kerker") {
55 return std::make_unique<KerkerPreconditioner>(
56 environment.g_squared, environment.q0_squared, environment.first_nonzero_g_index);
57 }
58 if (name == "local-tf") {
59 return std::make_unique<LocalThomasFermiPreconditioner>(environment.g_squared,
60 environment.q0_squared,
61 environment.first_nonzero_g_index,
62 environment.to_reciprocal_space,
63 environment.to_real_space,
64 environment.global_reduce);
65 }
66 throw std::runtime_error("Unknown mixing preconditioner: '" + name +
67 "'. Supported values: 'none', 'kerker', 'local-tf' "
68 "(or 'default' to choose by smearing).");
69}
70
71} // namespace PreconditionerFactory
72} // namespace q3
std::unique_ptr< Preconditioner > create(const std::string &name, const PreconditionerEnvironment &environment)
Create a residual preconditioner by name.
Definition factory.hpp:49
bool is_supported(const std::string &name)
The names create() accepts, for validation and error messages.
Definition factory.hpp:44
double Real
Everything any preconditioner needs from the surrounding representation.
Definition factory.hpp:31
Real q0_squared
Screening wavevector squared / vacuum floor, in bohr⁻².
Definition factory.hpp:33
std::vector< Real > g_squared
|G|² per G-vector, in bohr⁻².
Definition factory.hpp:32
std::function< void(const std::vector< Real > &, std::vector< Complex > &)> to_reciprocal_space
Definition factory.hpp:35
std::function< void(std::vector< Real > &)> global_reduce
Sums real-space integrals over the ranks sharing this pool's grid.
Definition factory.hpp:38
std::function< void(const std::vector< Complex > &, std::vector< Real > &)> to_real_space
Definition factory.hpp:36