-
Notifications
You must be signed in to change notification settings - Fork 6
Green's Functions #13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 5 commits
e95c43f
dbea9ae
88353d3
c4704b2
90c234a
2f9d5ee
e23c537
a5946ab
2ffd1e2
91e506b
5175a96
ebb7ef4
84b219d
65f56b3
e0ef771
9ab4627
414fdd1
302feef
a806f13
f02e8b0
a08ebf0
5baea2e
74702c2
d56989c
3241bc4
d4a7e4a
3d3277d
41cc116
a51b754
ff65ee7
b797e30
f838450
65db897
93e48e8
18415d5
e38bdbf
fa2442a
b2d334e
365a871
7e6eb02
8930b91
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,36 +30,91 @@ | |
| #include <utility> | ||
|
|
||
| #include "macis/gf/inn_prods.hpp" | ||
| #include "macis/solvers/davidson.hpp" | ||
|
|
||
| typedef std::numeric_limits<double> dbl; | ||
|
|
||
| namespace macis { | ||
|
|
||
| extern "C" { | ||
| extern int dgeqrf_(int *, int *, double *, int *, double *, double *, int *, | ||
| int *); | ||
| extern int dorgqr_(int *, int *, int *, double *, int *, double *, double *, | ||
| int *, int *); | ||
| extern int dsbtrd_(char *, char *, int *, int *, double *, int *, double *, | ||
| double *, double *, int *, double *, int *); | ||
| extern int dsytrd_(char *, int *, double *, int *, double *, double *, double *, | ||
| double *, int *, int *); | ||
| extern int dorgtr_(char *, int *, double *, int *, double *, double *, int *, | ||
| int *); | ||
| extern int dsteqr_(char *, int *, double *, double *, double *, int *, double *, | ||
| int *); | ||
| } | ||
|
|
||
| /** | ||
| * @ brief Wrapper for QR decomposition in LAPACK, basically | ||
| * calling dgeqrf and dorgqr to evaluate the R and | ||
| * Q matrices, which are returned. Here, the input | ||
| * matrix has more rows than columns. | ||
| * | ||
| * @param[inout] std::vector<std::vector<double> > &Q: On input, | ||
| * matrix for which to evaluate the QR decomposition. | ||
| * On output, Q-matrix. | ||
| * @param[out] std::vector<std::vector<double> > &R: On output, R | ||
| * matrix in the QR decomposition. | ||
| * | ||
| * @returns bool: Error code from LAPACK routines. | ||
| * | ||
| * @author Carlos Mejuto-Zaera | ||
| * @date 25/04/2022 | ||
| */ | ||
| bool QRdecomp(std::vector<std::vector<double> > &Q, | ||
| std::vector<std::vector<double> > &R); | ||
|
|
||
| /** | ||
| * @ brief Wrapper for QR decomposition in LAPACK, basically | ||
| * calling dgeqrf and dorgqr to evaluate the R and | ||
| * Q matrices, which are returned. Here, the input | ||
| * matrix has more columns than rows. | ||
| * | ||
| * @param[inout] std::vector<std::vector<double> > &Q: On input, | ||
| * matrix for which to evaluate the QR decomposition. | ||
| * On output, Q-matrix. | ||
| * @param[out] std::vector<std::vector<double> > &R: On output, R | ||
| * matrix in the QR decomposition. | ||
| * | ||
| * @returns bool: Error code from LAPACK routines. | ||
| * | ||
| * @author Carlos Mejuto-Zaera | ||
| * @date 25/04/2022 | ||
| */ | ||
| bool QRdecomp_tr(std::vector<std::vector<double> > &Q, | ||
| std::vector<std::vector<double> > &R); | ||
|
|
||
| /** | ||
| * @brief Wrapper to LAPACK routine to evaluate the eigenvectors | ||
| * and eigenvalues of the symmetric matrix mat. | ||
| * | ||
| * @param[inout] std::vector<std::vector<double> > &mat: Matrix for | ||
| * which to compute the eigenvalues/vectors. Erased | ||
| * during computation. | ||
| * @param[out] std::vector<double> &eigvals: Eigenvalues, sorted from smallest | ||
| * to largest. | ||
| * @param[out] std::vector<std::vector<double> > &eigvecs: Eigenvectors, | ||
| * stored as row vectors. | ||
| * | ||
| * @returns bool: Error code from LAPACK. | ||
| * | ||
| * @author Carlos Mejuto Zaera | ||
| * @date 25/04/2022 | ||
| */ | ||
| bool GetEigsys(std::vector<std::vector<double> > &mat, | ||
| std::vector<double> &eigvals, | ||
| std::vector<std::vector<double> > &eigvecs); | ||
|
|
||
| /** | ||
| * @brief Wrapper to LAPACK routine to evaluate the eigenvectors | ||
| * and eigenvalues of the symmetric band matrix mat. | ||
| * | ||
| * @param[inout] std::vector<std::vector<double> > &mat: Matrix for | ||
| * which to compute the eigenvalues/vectors. Erased | ||
| * during computation. | ||
| * @param[in] int nSupDiag: Nr. of bands. | ||
| * @param[out] std::vector<double> &eigvals: Eigenvalues, sorted from smallest | ||
| * to largest. | ||
| * @param[out] std::vector<std::vector<double> > &eigvecs: Eigenvectors, | ||
| * stored as row vectors. | ||
| * | ||
| * @returns bool: Error code from LAPACK. | ||
| * | ||
| * @author Carlos Mejuto Zaera | ||
| * @date 25/04/2022 | ||
| */ | ||
| bool GetEigsysBand(std::vector<std::vector<double> > &mat, int nSupDiag, | ||
| std::vector<double> &eigvals, | ||
| std::vector<std::vector<double> > &eigvecs); | ||
|
|
@@ -85,32 +140,35 @@ bool GetEigsysBand(std::vector<std::vector<double> > &mat, int nSupDiag, | |
| * @author Carlos Mejuto Zaera | ||
| * @date 25/04/2022 | ||
| */ | ||
| template <class Cont> | ||
| void MyBandLan( | ||
| const sparsexx::dist_sparse_matrix<sparsexx::csr_matrix<double, int32_t> > | ||
| &H, | ||
| std::vector<std::vector<Cont> > &qs, std::vector<std::vector<Cont> > &bandH, | ||
| int &nLanIts, double thres = 1.E-6, bool print = false) { | ||
| template <class Cont, class Functor> | ||
| void MyBandLan(const Functor &H, | ||
| // std::vector<std::vector<Cont> > &qs, | ||
| // std::vector<std::vector<Cont> > &bandH, | ||
| std::vector<Cont> &qs, std::vector<std::vector<Cont> > &bandH, | ||
| int &nLanIts, int nbands, int N, double thres = 1.E-6, | ||
| bool print = false) { | ||
| // BAND LANCZOS ROUTINE. TAKES AS INPUT THE HAMILTONIAN H, INITIAL VECTORS qs | ||
| // AND RETURNS THE BAND HAMILTONIAN bandH. IT PERFORMS nLanIts ITERATIONS, | ||
| // STOPPING IF THE NORM OF ANY NEW KRYLOV VECTOR IS BELOW thres. IF LANCZOS IS | ||
| // STOPPED PREMATURELY , nLanIts IS OVERWRITTEN WITH THE ACTUAL NUMBER OF | ||
| //ITERATIONS! THE qs VECTOR IS ERASED AT THE END OF THE CALCULATION | ||
| // ITERATIONS! THE qs VECTOR IS ERASED AT THE END OF THE CALCULATION | ||
| bandH.clear(); | ||
| bandH.resize(nLanIts, std::vector<Cont>(nLanIts, 0.)); | ||
|
|
||
| int nbands = qs.size(); | ||
| auto spmv_info = sparsexx::spblas::generate_spmv_comm_info(H); | ||
| // MAKE SPACE FOR 2 * nbands VECTORS | ||
| qs.resize(2 * nbands, std::vector<Cont>(qs[0].size(), 0.)); | ||
| std::vector<Cont> temp(qs[0].size(), 0.); | ||
| // qs.resize(2 * nbands, std::vector<Cont>(qs[0].size(), 0.)); | ||
| qs.resize(2 * nbands * N); | ||
| // std::vector<Cont> temp(qs[0].size(), 0.); | ||
| std::vector<Cont> temp(N, 0.); | ||
| if(print) { | ||
| for(int i = 0; i < nbands; i++) { | ||
| std::ofstream ofile("lanvec_" + std::to_string(i + 1) + ".dat", | ||
| std::ios::out); | ||
| ofile.precision(dbl::max_digits10); | ||
| for(size_t el = 0; el < qs[i].size(); el++) | ||
| ofile << std::scientific << qs[i][el] << std::endl; | ||
| // for(size_t el = 0; el < qs[i].size(); el++) | ||
| for(size_t el = 0; el < N; el++) | ||
| // ofile << std::scientific << qs[i][el] << std::endl; | ||
| ofile << std::scientific << qs[el + i * N] << std::endl; | ||
| ofile.close(); | ||
| } | ||
| } | ||
|
|
@@ -125,8 +183,10 @@ void MyBandLan( | |
| for(int it = 1; it <= nLanIts; it++) { | ||
| int band_indx_i = | ||
| true_indx[it]; // TO WHAT ELEMENT OF THE VECTOR SET DO WE APPLY THIS | ||
|
Owner
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you explain this indirection here? Generally we want to avoid things like this (to e.g. allow for better usage of Level-3 BLAS when possible), but if its completely necessary, it's fine.
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean the use of the effective index This is what I came up with to apply the matvecs in the right order to the right vector, since in band Lanczos, unlike in the regular one, at every iteration you act on a different vector in your set of I guess that a way to avoid this |
||
| sparsexx::spblas::pgespmv(1., H, qs[band_indx_i].data(), 0., temp.data(), | ||
| spmv_info); | ||
| // H.operator_action( 1, 1., qs[band_indx_i].data(), temp.size(), 0., | ||
| // temp.data(), temp.size() ); | ||
| H.operator_action(1, 1., qs.data() + band_indx_i * N, N, 0., temp.data(), | ||
| N); | ||
| if(print) { | ||
| std::ofstream ofile("Htimes_lanvec_" + std::to_string(it) + ".dat", | ||
| std::ios::out); | ||
|
|
@@ -140,15 +200,19 @@ void MyBandLan( | |
| int band_indx_j = true_indx[jt]; | ||
| #pragma omp parallel for | ||
| for(size_t coeff = 0; coeff < temp.size(); coeff++) | ||
| temp[coeff] -= bandH[it - 1][jt - 1] * qs[band_indx_j][coeff]; | ||
| // temp[coeff] -= bandH[it - 1][jt - 1] * qs[band_indx_j][coeff]; | ||
| temp[coeff] -= bandH[it - 1][jt - 1] * qs[N * band_indx_j + coeff]; | ||
| } | ||
| for(int jt = it; jt <= std::min(it + nbands - 1, nLanIts); jt++) { | ||
| int band_indx_j = true_indx[jt]; | ||
| bandH[it - 1][jt - 1] = MyInnProd(temp, qs[band_indx_j]); | ||
| // bandH[it - 1][jt - 1] = MyInnProd(temp, qs[band_indx_j]); | ||
| bandH[it - 1][jt - 1] = | ||
| blas::dot(N, temp.data(), 1, qs.data() + band_indx_j * N, 1); | ||
| bandH[jt - 1][it - 1] = bandH[it - 1][jt - 1]; | ||
| #pragma omp parallel for | ||
| for(size_t coeff = 0; coeff < temp.size(); coeff++) | ||
| temp[coeff] -= bandH[it - 1][jt - 1] * qs[band_indx_j][coeff]; | ||
| // temp[coeff] -= bandH[it - 1][jt - 1] * qs[band_indx_j][coeff]; | ||
| temp[coeff] -= bandH[it - 1][jt - 1] * qs[N * band_indx_j + coeff]; | ||
| } | ||
| if(it + nbands <= nLanIts) { | ||
| bandH[it - 1][it + nbands - 1] = | ||
|
|
@@ -166,20 +230,24 @@ void MyBandLan( | |
| break; | ||
| #pragma omp parallel for | ||
| for(size_t coeff = 0; coeff < temp.size(); coeff++) | ||
|
||
| qs[true_indx[it + nbands]][coeff] = 0.; | ||
| // qs[true_indx[it + nbands]][coeff] = 0.; | ||
| qs[true_indx[it + nbands] * N + coeff] = 0.; | ||
| std::cout << "FOUND A ZERO VECTOR AT POSITION " << next_indx | ||
| << std::endl; | ||
| } else { | ||
| #pragma omp parallel for | ||
| for(size_t coeff = 0; coeff < temp.size(); coeff++) | ||
|
||
| qs[true_indx[it + nbands]][coeff] = | ||
| // qs[true_indx[it + nbands]][coeff] = | ||
| qs[true_indx[it + nbands] * N + coeff] = | ||
| temp[coeff] / bandH[it - 1][it + nbands - 1]; | ||
| if(print) { | ||
| std::ofstream ofile("lanvec_" + std::to_string(it + nbands) + ".dat", | ||
| std::ios::out); | ||
| ofile.precision(dbl::max_digits10); | ||
| for(size_t el = 0; el < qs[true_indx[it + nbands]].size(); el++) | ||
| ofile << std::scientific << qs[true_indx[it + nbands]][el] | ||
| // for(size_t el = 0; el < qs[true_indx[it + nbands]].size(); el++) | ||
| for(size_t el = 0; el < N; el++) | ||
| // ofile << std::scientific << qs[true_indx[it + nbands]][el] | ||
| ofile << std::scientific << qs[true_indx[it + nbands] * N + el] | ||
| << std::endl; | ||
| ofile.close(); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -32,14 +32,7 @@ namespace macis { | |
| */ | ||
| inline double MyInnProd(const std::vector<double>& vecR, | ||
wavefunction91 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| const std::vector<double>& vecL) { | ||
| // SIMPLE INNER PRODUCT ROUTINE | ||
| double res = 0.; | ||
| #pragma omp declare reduction(Vsum:double \ | ||
| : omp_out = omp_out + omp_in) \ | ||
| initializer(omp_priv = 0.) | ||
| #pragma omp parallel for reduction(Vsum : res) | ||
| for(size_t i = 0; i < vecR.size(); i++) res += vecR[i] * vecL[i]; | ||
| return res; | ||
| return blas::dot(vecR.size(), vecR.data(), 1, vecL.data(), 1); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -56,14 +49,7 @@ inline double MyInnProd(const std::vector<double>& vecR, | |
| inline std::complex<double> MyInnProd( | ||
wavefunction91 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| const std::vector<std::complex<double> >& vecR, | ||
| const std::vector<std::complex<double> >& vecL) { | ||
| // SIMPLE INNER PRODUCT ROUTINE | ||
| std::complex<double> res(0., 0.); | ||
| #pragma omp declare reduction \ | ||
| (Vsum:std::complex<double>:omp_out=omp_out+omp_in)\ | ||
| initializer(omp_priv=std::complex<double>(0.,0.)) | ||
| #pragma omp parallel for reduction(Vsum : res) | ||
| for(size_t i = 0; i < vecR.size(); i++) res += conj(vecR[i]) * vecL[i]; | ||
| return res; | ||
| return blas::dot(vecR.size(), vecR.data(), 1, vecL.data(), 1); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -80,15 +66,7 @@ inline std::complex<double> MyInnProd( | |
| inline std::complex<double> MyInnProd( | ||
wavefunction91 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| const std::vector<std::complex<double> >& vecR, | ||
| const std::vector<double>& vecL) { | ||
| // SIMPLE INNER PRODUCT ROUTINE | ||
| std::complex<double> res(0., 0.); | ||
| #pragma omp declare reduction \ | ||
| (Vsum:std::complex<double>:omp_out=omp_out+omp_in)\ | ||
| initializer(omp_priv=std::complex<double>(0.,0.)) | ||
| #pragma omp parallel for reduction(Vsum : res) | ||
| for(size_t i = 0; i < vecR.size(); i++) | ||
| res += conj(vecR[i]) * std::complex<double>(vecL[i], 0.); | ||
| return res; | ||
| return blas::dot(vecR.size(), vecR.data(), 1, vecL.data(), 1); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -103,8 +81,7 @@ inline std::complex<double> MyInnProd( | |
| */ | ||
| inline std::complex<double> MyInnProd(const Eigen::VectorXcd& vecR, | ||
wavefunction91 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| const Eigen::VectorXcd& vecL) { | ||
| // SIMPLE INNER PRODUCT ROUTINE | ||
| return vecR.dot(vecL); | ||
| return blas::dot(vecR.size(), vecR.data(), 1, vecL.data(), 1); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -119,7 +96,6 @@ inline std::complex<double> MyInnProd(const Eigen::VectorXcd& vecR, | |
| */ | ||
| inline double MyInnProd(const Eigen::VectorXd& vecR, | ||
wavefunction91 marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| const Eigen::VectorXd& vecL) { | ||
| // SIMPLE INNER PRODUCT ROUTINE | ||
| return vecR.dot(vecL); | ||
| return blas::dot(vecR.size(), vecR.data(), 1, vecL.data(), 1); | ||
| } | ||
| } // namespace macis | ||
Uh oh!
There was an error while loading. Please reload this page.