48 : energy_cutoff_wavefunction_(config.energy_cutoff_wavefunction)
49 , energy_cutoff_charge_density_(config.energy_cutoff_charge_density) {
50 if (energy_cutoff_charge_density_ <= 0.0) {
51 energy_cutoff_charge_density_ = 4.0 * energy_cutoff_wavefunction_;
59 const Crystal& crystal_structure,
63 bool use_measured_fft_planning =
true,
64 bool use_exact_wavefunction_grid =
false) {
68 if (energy_cutoff_charge_density_ <= 0.0) {
69 energy_cutoff_charge_density_ = 4.0 * energy_cutoff_wavefunction_;
73 energy_cutoff_charge_density_,
74 energy_cutoff_wavefunction_,
75 use_measured_fft_planning,
76 use_exact_wavefunction_grid);
82 g_vectors_.
generate(crystal_structure,
83 energy_cutoff_charge_density_,
108 template <
typename Predicate>
110 Predicate accept)
const {
114 std::vector<int> weights(
static_cast<std::size_t
>(dimension_1) * dimension_2, 0);
115 for (
const auto& g_vector : g_vectors_.
g_vectors()) {
116 int miller_1 =
static_cast<int>(std::lround(g_vector.miller.x));
117 int miller_2 =
static_cast<int>(std::lround(g_vector.miller.y));
118 int miller_3 =
static_cast<int>(std::lround(g_vector.miller.z));
119 if (std::abs(miller_1) > dimension_1 / 2 || std::abs(miller_2) > dimension_2 / 2 ||
120 std::abs(miller_3) > dimension_3 / 2 || !accept(g_vector)) {
123 int wrapped_1 = miller_1 >= 0 ? miller_1 : miller_1 + dimension_1;
124 int wrapped_2 = miller_2 >= 0 ? miller_2 : miller_2 + dimension_2;
125 weights[
static_cast<std::size_t
>(wrapped_1) * dimension_2 + wrapped_2] += 1;
137 for (
auto& weight : weights) {
138 weight = std::max(weight, 1);
148 [[nodiscard]]
const std::vector<GVector>&
g_vectors()
const {
158 return is_gamma_only_;
173 return gamma_origin_is_local_;
179 const Crystal& crystal_structure,
180 std::vector<int>& g_vector_indices,
181 std::vector<Real>& kinetic_energy_squared,
182 int band_size = 1)
const {
187 const FFTGrid* fft_wave_ptr = (band_size > 1) ? &fft_pair_.
fft_wave() :
nullptr;
191 energy_cutoff_wavefunction_,
193 kinetic_energy_squared,
199 return maximum_plane_waves_per_kpoint_;
214 Real largest_k = 0.0;
216 const auto& k = kpoint_grid[index].coordinates;
218 for (
int dimension = 0; dimension < 3; ++dimension) {
219 k_cartesian[dimension] = k.
x * reciprocal[0][dimension] +
220 k.y * reciprocal[1][dimension] +
221 k.z * reciprocal[2][dimension];
223 largest_k = std::max(largest_k, std::sqrt(k_cartesian.
norm2()));
226 std::sqrt(energy_cutoff_wavefunction_ /
228 Real radius_squared = (cutoff_radius + largest_k) * (cutoff_radius + largest_k) *
232 return g.g_cart.norm2() <= radius_squared;
236 const FFTGrid* fft_wave_ptr = (band_size > 1) ? &fft_pair_.
fft_wave() :
nullptr;
240 energy_cutoff_wavefunction_,
249 gamma_origin_is_local_ =
true;
252 gamma_origin_is_local_ =
254 g_vectors_.
g_vectors()[
static_cast<std::size_t
>(indices[0])].magnitude_squared <
267 [[nodiscard]]
const std::vector<Real>&
304 void g_to_r(
const std::vector<Complex>& coefficients_g_space,
305 const std::vector<int>& g_vector_indices,
306 int number_of_plane_waves,
307 std::vector<Complex>& coefficients_real_space)
const {
310 coefficients_g_space,
312 number_of_plane_waves,
313 coefficients_real_space);
316 void r_to_g(
const std::vector<Complex>& coefficients_real_space,
317 const std::vector<int>& g_vector_indices,
318 int number_of_plane_waves,
319 std::vector<Complex>& coefficients_g_space)
const {
322 coefficients_real_space,
324 number_of_plane_waves,
325 coefficients_g_space);
328 void rho_g_to_r(
const std::vector<Complex>& charge_density_g_space,
329 std::vector<Real>& charge_density_real_space)
const {
331 g_vectors_, fft_pair_.
fft_rho(), charge_density_g_space, charge_density_real_space);
334 void rho_r_to_g(
const std::vector<Real>& charge_density_real_space,
335 std::vector<Complex>& charge_density_g_space)
const {
337 g_vectors_, fft_pair_.
fft_rho(), charge_density_real_space, charge_density_g_space);
343 return energy_cutoff_wavefunction_;
346 return energy_cutoff_charge_density_;
358 return plane_wave_table_;
362 Real energy_cutoff_wavefunction_{};
363 Real energy_cutoff_charge_density_{};
364 PlanewaveFFTPair fft_pair_;
365 GVectorsGrid g_vectors_;
366 PlaneWaveTable plane_wave_table_;
367 int maximum_plane_waves_per_kpoint_{};
368 bool is_gamma_only_{
false};
369 bool gamma_origin_is_local_{
true};
Real two_pi_over_lattice_parameter_squared() const
const Matrix3x3 & reciprocal_lattice_vectors() const
virtual void assign_sticks(const std::vector< int > &)
virtual int grid_dimension_1() const =0
virtual int grid_dimension_3() const =0
virtual int grid_dimension_2() const =0
const std::vector< Real > & g_vector_magnitudes() const
void generate(const Crystal &crystal_structure, Real energy_cutoff_charge_density, int grid_dimension_1, int grid_dimension_2, int grid_dimension_3, bool is_gamma_only=false, int rank=0, int size=1, int fft_local_start=-1, int fft_local_dimension_1=-1)
int estimate_maximum_plane_waves_per_kpoint(Real energy_cutoff_wavefunction, Real two_pi_over_lattice_parameter_squared) const
const std::vector< GVector > & g_vectors() const
int number_of_g_vectors() const
int first_nonzero_g_index() const
int number_of_kpoints() const
static void select(const GVectorsGrid &g_vectors_grid, const Vector3D &k_coordinates, const Crystal &crystal_structure, Real energy_cutoff_wavefunction, std::vector< int > &g_vector_indices, std::vector< Real > &kinetic_energy_squared, const FFTGrid *fft_wave=nullptr, int band_size=1)
const std::vector< std::vector< Real > > & kpoint_kinetic_energy_squared() const
const std::vector< int > & g_vector_indices_by_kpoint_index(int kpoint_index) const
void initialize(const GVectorsGrid &g_vectors_grid, const Crystal &crystal_structure, const KPointsGrid &kpoint_grid, Real energy_cutoff_wavefunction, const FFTGrid *fft_wave=nullptr, int band_size=1)
const std::vector< std::vector< int > > & kpoint_g_vector_indices() const
const std::vector< Real > & kinetic_energy_squared_by_kpoint_index(int kpoint_index) const
const std::vector< int > & kpoint_number_of_plane_waves() const
int number_of_plane_waves_by_kpoint_index(int kpoint_index) const
int number_of_g_vectors() const
void rho_g_to_r(const std::vector< Complex > &charge_density_g_space, std::vector< Real > &charge_density_real_space) const
std::vector< int > stick_weights_for_grid(const FFTGrid &grid, Predicate accept) const
const std::vector< GVector > & g_vectors() const
const PlanewaveFFTPair & fft_pair() const
Real wavefunction_energy_cutoff() const
const PlaneWaveTable & plane_wave_table() const
const FFTGrid & fft_wave() const
void initialize_kpoint_data(const Crystal &crystal_structure, const KPointsGrid &kpoint_grid, int band_size=1)
void rho_r_to_g(const std::vector< Real > &charge_density_real_space, std::vector< Complex > &charge_density_g_space) const
int first_nonzero_g_index() const
void g_to_r(const std::vector< Complex > &coefficients_g_space, const std::vector< int > &g_vector_indices, int number_of_plane_waves, std::vector< Complex > &coefficients_real_space) const
const std::vector< int > & g_vector_indices_by_kpoint_index(int kpoint_index) const
const std::vector< std::vector< int > > & kpoint_g_vector_indices() const
Real charge_density_energy_cutoff() const
int number_of_plane_waves_by_kpoint_index(int kpoint_index) const
const GVectorsGrid & g_vectors_grid() const
int maximum_plane_waves_per_kpoint() const
const SerialFFTGrid & fft_wave_serial() const
void r_to_g(const std::vector< Complex > &coefficients_real_space, const std::vector< int > &g_vector_indices, int number_of_plane_waves, std::vector< Complex > &coefficients_g_space) const
void generate(const FFTGridFactory &fft_grid_factory, const Crystal &crystal_structure, Real wavefunction_energy_cutoff, Real charge_density_energy_cutoff, bool is_gamma_only=false, bool use_measured_fft_planning=true, bool use_exact_wavefunction_grid=false)
bool gamma_origin_is_local() const
const FFTGrid & fft_rho() const
void compute_gk(const Vector3D &k_coordinates, const Crystal &crystal_structure, std::vector< int > &g_vector_indices, std::vector< Real > &kinetic_energy_squared, int band_size=1) const
const std::vector< Real > & kinetic_energy_squared_by_kpoint_index(int kpoint_index) const
const std::vector< std::vector< Real > > & kpoint_kinetic_energy_squared() const
const std::vector< int > & kpoint_number_of_plane_waves() const
bool is_gamma_only() const
PlanewaveBasis(PlanewaveBasisConfig config)
const std::vector< Real > & g_vector_magnitudes() const
const SerialFFTGrid & fft_wave_serial() const
void initialize(const FFTGridFactory &fft_grid_factory, const Crystal &crystal_structure, Real energy_cutoff_charge_density, Real energy_cutoff_wavefunction, bool use_measured_fft_planning=true, bool use_exact_wavefunction_grid=false)
constexpr double numerical_zero_threshold
constexpr double energy_cutoff_rounding_tolerance
A reciprocal lattice vector with Miller indices, used in plane-wave calculations.
Real energy_cutoff_wavefunction
Wavefunction energy cutoff in Rydberg.
Real energy_cutoff_charge_density
Charge density energy cutoff in Rydberg (typically 4× wavefunction cutoff for NC PP).