Loading...
Searching...
No Matches
init.hpp
Go to the documentation of this file.
1#pragma once
2
3/**
4 * BetaFunctionTable — tabulated beta projector functions on a uniform q-grid.
5 *
6 * This base class knows exactly one way to obtain β(q): the spherical Bessel
7 * transform of a radially tabulated r·β(r), which is what every UPF dataset
8 * (norm-conserving, ultrasoft, and UPF-PAW alike) supplies. It knows nothing
9 * about any other representation, deliberately: dataset flavors that carry
10 * their projectors differently override tabulate_projector() in their own
11 * subclass (see beta_function_table/paw.hpp), and the factory in
12 * beta_function_table/factory.hpp picks the right table for a pseudopotential
13 * set. Shared plane-wave code stays free of flavor-specific includes and
14 * casts.
15 *
16 * The override point is per projector, not per table, because a single
17 * calculation may mix dataset flavors across species — a subclass falls back
18 * to this base implementation for species it has nothing special to say
19 * about.
20 */
21
22#include <cmath>
23#include <vector>
24
32
33namespace q3 {
34
36 public:
37 BetaFunctionTable() = default;
38 virtual ~BetaFunctionTable() = default;
39
40 /**
41 * Initialize the q-grid and tabulate beta functions for all species.
42 */
43 void initialize(const PlanewaveBasis& planewave_basis,
44 const PseudopotentialSet& pseudopotential_set,
45 int number_of_species_types) {
46 static constexpr Real q_range_padding_factor = 1.1;
47 Real maximum_q_value =
48 std::sqrt(planewave_basis.charge_density_energy_cutoff()) * q_range_padding_factor;
49 q_grid_ =
51
52 tabulate_all(pseudopotential_set, number_of_species_types);
53 }
54
55 /**
56 * Initialize using a pre-built shared q-grid.
57 */
59 const PseudopotentialSet& pseudopotential_set,
60 int number_of_species_types) {
61 q_grid_ = q_grid;
62 tabulate_all(pseudopotential_set, number_of_species_types);
63 }
64
65 [[nodiscard]] Real interpolate(int species_type_index, int beta_index, Real q_value) const {
66 return table_[species_type_index][beta_index].interpolate(q_value);
67 }
68
69 [[nodiscard]] Real
70 interpolate_derivative(int species_type_index, int beta_index, Real q_value) const {
71 return table_[species_type_index][beta_index].interpolate_derivative(q_value);
72 }
73
74 [[nodiscard]] const UniformQGrid& q_grid() const {
75 return q_grid_;
76 }
77
78 [[nodiscard]] int number_of_q_points() const {
79 return q_grid_.number_of_q_points;
80 }
81
82 [[nodiscard]] Real q_spacing() const {
83 return q_grid_.q_spacing;
84 }
85
86 protected:
87 /**
88 * Fill one projector's β(q) at the given q values.
89 *
90 * The base implementation is the spherical Bessel transform of the
91 * dataset's radial r·β(r). Subclasses override this per projector when the
92 * dataset supplies β in another representation, and may call this base
93 * implementation as the fallback for species they do not handle.
94 */
95 virtual void tabulate_projector(const Pseudopotential& pseudopotential,
96 int projector_index,
97 const std::vector<Real>& q_point_values,
98 std::vector<Real>& destination) const {
99 const auto& projector = pseudopotential.projectors[projector_index];
101 pseudopotential.radial_grid_derivative,
102 projector.radial_values,
103 projector.angular_momentum,
104 projector.number_of_radial_cutoff_points,
105 q_point_values,
106 destination);
107 }
108
109 private:
110 void tabulate_all(const PseudopotentialSet& pseudopotential_set, int number_of_species_types) {
111 std::vector<Real> q_point_values = q_grid_.q_point_values();
112
113 table_.resize(number_of_species_types);
114 for (int type_index = 0; type_index < number_of_species_types; type_index++) {
115 const auto& pseudopotential = pseudopotential_set[type_index];
116 table_[type_index].resize(pseudopotential.number_of_projectors);
117 for (int projector_index = 0; projector_index < pseudopotential.number_of_projectors;
118 projector_index++) {
119 table_[type_index][projector_index].resize(q_grid_);
120 tabulate_projector(pseudopotential,
121 projector_index,
122 q_point_values,
123 table_[type_index][projector_index].values());
124 }
125 }
126 }
127
128 UniformQGrid q_grid_;
129 std::vector<std::vector<UniformQGridTable>> table_;
130};
131
132} // namespace q3
Real q_spacing() const
Definition init.hpp:82
virtual ~BetaFunctionTable()=default
virtual void tabulate_projector(const Pseudopotential &pseudopotential, int projector_index, const std::vector< Real > &q_point_values, std::vector< Real > &destination) const
Definition init.hpp:95
void initialize(const PlanewaveBasis &planewave_basis, const PseudopotentialSet &pseudopotential_set, int number_of_species_types)
Definition init.hpp:43
const UniformQGrid & q_grid() const
Definition init.hpp:74
void initialize(const UniformQGrid &q_grid, const PseudopotentialSet &pseudopotential_set, int number_of_species_types)
Definition init.hpp:58
Real interpolate(int species_type_index, int beta_index, Real q_value) const
Definition init.hpp:65
int number_of_q_points() const
Definition init.hpp:78
BetaFunctionTable()=default
Real interpolate_derivative(int species_type_index, int beta_index, Real q_value) const
Definition init.hpp:70
Real charge_density_energy_cutoff() const
Definition init.hpp:345
Base class for all pseudopotential types.
Definition init.hpp:35
std::vector< Real > radial_grid_derivative
Definition init.hpp:77
std::vector< Projector > projectors
Definition init.hpp:80
std::vector< Real > radial_grid
Definition init.hpp:76
constexpr double default_q_grid_spacing
double Real
void transform_spherical_bessel(const std::vector< Real > &grid, const std::vector< Real > &integration_factors, const std::vector< Real > &function, int degree, int mesh_size, const std::vector< Real > &q_points, std::vector< Real > &fourier_transform)
std::vector< Real > q_point_values() const
static UniformQGrid from_maximum_q(Real maximum_q_value, Real q_spacing)