Skip to content

Commit da09339

Browse files
authored
Add DiagoPPCG header file for gamma-point PPCG
Add diago_ppcg,h to the branch, yet some changes in CMake needed.
1 parent 0dd7bd4 commit da09339

1 file changed

Lines changed: 142 additions & 0 deletions

File tree

source/source_hsolver/diago_ppcg.h

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
#ifndef DIAGO_PPCG_H_
2+
#define DIAGO_PPCG_H_
3+
4+
#include "source_base/module_device/types.h"
5+
#include "source_base/macros.h"
6+
7+
#include <algorithm>
8+
#include <cmath>
9+
#include <complex>
10+
#include <functional>
11+
#include <numeric>
12+
#include <stdexcept>
13+
#include <string>
14+
#include <vector>
15+
16+
namespace hsolver
17+
{
18+
19+
/**
20+
* @brief Gamma-point PPCG draft for source_hsolver.
21+
*
22+
* Notes:
23+
* 1. This file is intentionally aligned with the source_hsolver naming/interface style.
24+
* 2. The implementation below is a CPU-first draft and follows the uploaded ppcg_gamma.f90 logic.
25+
* 3. Projected matrices are treated as real-symmetric by using gamma-point real inner products.
26+
* 4. This is not a full MPI / band-group / GPU port of the original QE Fortran implementation.
27+
*/
28+
template <typename T = std::complex<double>, typename Device = base_device::DEVICE_CPU>
29+
class DiagoPPCG final
30+
{
31+
private:
32+
using Real = typename GetTypeReal<T>::type;
33+
34+
public:
35+
using HPsiFunc = std::function<void(T*, T*, const int, const int)>;
36+
using SPsiFunc = std::function<void(T*, T*, const int, const int)>;
37+
38+
DiagoPPCG(const Real& diag_thr,
39+
const int& diag_iter_max,
40+
const int& sbsize = 4,
41+
const int& rr_step = 2,
42+
const bool gamma_g0_real = true);
43+
44+
double diag(const HPsiFunc& hpsi_func,
45+
const SPsiFunc& spsi_func,
46+
const int ld_psi,
47+
const int nband,
48+
const int dim,
49+
T* psi_in,
50+
Real* eigenvalue_in,
51+
const std::vector<double>& ethr_band,
52+
const Real* prec = nullptr);
53+
54+
private:
55+
struct SmallSubspace
56+
{
57+
std::vector<Real> k;
58+
std::vector<Real> m;
59+
std::vector<Real> eval;
60+
};
61+
62+
int ld_psi_ = 0;
63+
int n_band_ = 0;
64+
int n_dim_ = 0;
65+
int maxter_ = 0;
66+
int sbsize_ = 1;
67+
int rr_step_ = 1;
68+
69+
Real diag_thr_ = static_cast<Real>(1.0e-8);
70+
bool gamma_g0_real_ = true;
71+
72+
std::vector<T> hpsi_;
73+
std::vector<T> w_;
74+
std::vector<T> hw_;
75+
std::vector<T> p_;
76+
std::vector<T> hp_;
77+
78+
static int idx(const int i, const int j, const int ld)
79+
{
80+
return i + j * ld;
81+
}
82+
83+
void validate_input(T* psi_in, Real* eigenvalue_in, const Real* prec) const;
84+
void force_g0_real(T* x, const int ncol) const;
85+
86+
void apply_h(const HPsiFunc& hpsi_func, T* psi_in, T* hpsi_out, const int ncol) const;
87+
void apply_s(const SPsiFunc& spsi_func, T* psi_in, T* spsi_out, const int ncol) const;
88+
89+
Real gamma_dot(const T* x, const T* y) const;
90+
91+
void gram(const T* a,
92+
const T* b,
93+
const int ncol_a,
94+
const int ncol_b,
95+
std::vector<Real>& out,
96+
const int ld_out) const;
97+
98+
void copy_cols(const T* src, const std::vector<int>& cols, std::vector<T>& dst) const;
99+
void scatter_cols(T* dst, const std::vector<int>& cols, const std::vector<T>& src) const;
100+
101+
void project_against(const T* basis,
102+
const std::vector<int>& basis_cols,
103+
std::vector<T>& x,
104+
const std::vector<int>& x_cols) const;
105+
106+
void divide_by_preconditioner(const std::vector<int>& active_cols,
107+
const Real* prec,
108+
std::vector<T>& x) const;
109+
110+
void lock_epairs(const std::vector<T>& residual,
111+
const std::vector<double>& ethr_band,
112+
std::vector<int>& active_cols) const;
113+
114+
void build_small_subspace(const T* psi,
115+
const std::vector<int>& cols,
116+
const bool use_p,
117+
SmallSubspace& subspace) const;
118+
119+
void solve_small_generalized(const int dim, SmallSubspace& subspace) const;
120+
121+
void update_one_block(T* psi,
122+
const std::vector<int>& cols,
123+
const int l,
124+
const bool use_p,
125+
const SmallSubspace& subspace) const;
126+
127+
void chol_qr_active(T* psi, const std::vector<int>& active_cols) const;
128+
void right_solve_upper_real(const std::vector<Real>& r,
129+
const int n,
130+
std::vector<T>& x) const;
131+
132+
void rayleigh_ritz(T* psi,
133+
Real* eigenvalue,
134+
std::vector<int>& active_cols,
135+
const std::vector<double>& ethr_band);
136+
137+
Real trace_of_active_projected(const T* psi, const std::vector<int>& active_cols) const;
138+
};
139+
140+
} // namespace hsolver
141+
142+
#endif // DIAGO_PPCG_H_

0 commit comments

Comments
 (0)