Skip to content

Commit 8267e1e

Browse files
committed
updated Wannier function in the vrnl method.
1 parent bc4352e commit 8267e1e

File tree

2 files changed

+69
-11
lines changed

2 files changed

+69
-11
lines changed

src/model.cc

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1971,21 +1971,22 @@ namespace qbasis {
19711971
lanczos(0, maxit-1, maxit, m, dim, HamMat, vec_new.data(), hessenberg, "dnmcs");
19721972
}
19731973

1974-
//const std::vector<std::pair<std::vector<double>,mopr<T>>> Ar_list,
19751974
template <typename T>
1976-
void model<T>::WannierMat_vrnl(
1975+
void model<T>::WannierMat_vrnl(const std::vector<std::pair<std::vector<double>,mopr<T>>> &Ar_list,
19771976
const uint32_t &sec_vrnl,
19781977
const std::vector<std::vector<double>> &momenta_list,
1979-
std::vector<std::complex<double>> &matrix_mu_list,
1978+
std::vector<std::complex<double>> &matrix_mu,
19801979
const std::function<MKL_INT(const model<T>&, const uint32_t&)> &locate_state)
19811980
{
1982-
assert(sec_vrnl < basis_vrnl.size());
1981+
assert(sec_vrnl < basis_vrnl.size() - 1);
19831982

19841983
MKL_INT dim = dim_vrnl[sec_vrnl];
19851984
auto &basis = basis_vrnl[sec_vrnl];
19861985
assert(static_cast<MKL_INT>(basis.size()) == dim);
19871986
uint32_t num_k = momenta_list.size();
1988-
matrix_mu_list.resize(num_k * num_k);
1987+
matrix_mu.resize(num_k * num_k);
1988+
1989+
std::cout << "Building Wannier Matrix..." << std::endl;
19891990

19901991
// first check if eigenstates already built
19911992
bool states_built;
@@ -2053,30 +2054,88 @@ namespace qbasis {
20532054
}
20542055
}
20552056

2057+
// return Bq
2058+
auto FourierTR = [](const std::vector<std::pair<std::vector<double>,mopr<T>>> &Ar_list,
2059+
const std::vector<double> &q)
2060+
{
2061+
mopr<T> Bq;
2062+
assert(q.size() == Ar_list[0].first.size());
2063+
for (decltype(Ar_list.size()) j = 0; j < Ar_list.size(); j++) {
2064+
double expcoef = 0.0;
2065+
for (uint32_t d = 0; d < q.size(); d++) expcoef += Ar_list[j].first[d] * q[d];
2066+
std::complex<double> temp = std::exp(std::complex<double>(0.0,expcoef));
2067+
Bq += temp * Ar_list[j].second;
2068+
}
2069+
return Bq;
2070+
};
2071+
2072+
2073+
// temporarily use the last sector
2074+
uint32_t sec_new = dim_vrnl.size() - 1;
2075+
dim_vrnl[sec_new] = dim_vrnl[sec_vrnl];
2076+
basis_vrnl[sec_new] = basis_vrnl[sec_vrnl];
2077+
2078+
2079+
// build the matrix
20562080
std::vector<std::complex<double>> eigvec_k1(dim);
20572081
std::vector<std::complex<double>> eigvec_k2(dim);
2082+
std::vector<std::complex<double>> vec_new(dim);
2083+
T pG;
20582084
for (uint32_t k2_idx = 0; k2_idx < num_k; k2_idx++) {
20592085
// read out phi(k2)
20602086
std::string vec_filek2 = "out_Wannier/eigvec_" + std::to_string(k2_idx) + ".dat";
20612087
int info2 = vec_disk_read(vec_filek2, dim, eigvec_k2.data());
20622088
assert(info2 == 0);
20632089

2090+
// re-calculate the GS normalization factor for k2_idx
2091+
momenta_vrnl[sec_vrnl] = momenta_list[k2_idx];
2092+
auto momentum_dis_k2 = momenta_vrnl[sec_vrnl];
2093+
for (uint32_t d = 0; d < momentum_dis_k2.size(); d++) momentum_dis_k2[d] -= gs_momentum_vrnl[d];
2094+
auto dis_gs_nrm2_k2 = nrm2(static_cast<MKL_INT>(momentum_dis_k2.size()), momentum_dis_k2.data(), 1);
2095+
gs_norm_vrnl[sec_vrnl] = dis_gs_nrm2_k2 > lanczos_precision ? 0 : gs_omegaG_vrnl;
2096+
20642097
for (uint32_t k1_idx = 0; k1_idx <= k2_idx; k1_idx++) {
20652098
// read out phi(k1)
20662099
std::string vec_filek1 = "out_Wannier/eigvec_" + std::to_string(k1_idx) + ".dat";
20672100
int info1 = vec_disk_read(vec_filek1, dim, eigvec_k1.data());
20682101
assert(info1 == 0);
20692102

2103+
// q = k1-k2
2104+
auto q_transfer = momenta_list[k1_idx];
2105+
for (uint32_t d = 0; d < q_transfer.size(); d++) q_transfer[d] -= momenta_list[k2_idx][d];
2106+
20702107
// now need contruct B_{k1-k2}
2108+
auto Bq = FourierTR(Ar_list, q_transfer);
20712109

2110+
std::cout << " --------- progress --------" << std::endl;
2111+
std::cout << " k2: " << k2_idx << " / " << num_k << std::endl;
2112+
std::cout << " k1: " << k1_idx << " / " << num_k << std::endl;
20722113

2114+
// re-calculate the GS normalization factor for k1_idx
2115+
momenta_vrnl[sec_new] = momenta_list[k1_idx];
2116+
auto momentum_dis_k1 = momenta_vrnl[sec_new];
2117+
for (uint32_t d = 0; d < momentum_dis_k1.size(); d++) momentum_dis_k1[d] -= gs_momentum_vrnl[d];
2118+
auto dis_gs_nrm2_k1 = nrm2(static_cast<MKL_INT>(momentum_dis_k1.size()), momentum_dis_k1.data(), 1);
2119+
gs_norm_vrnl[sec_new] = dis_gs_nrm2_k1 > lanczos_precision ? 0 : gs_omegaG_vrnl;
20732120

2121+
moprXvec_vrnl(Bq, sec_vrnl, sec_new, eigvec_k2.data(), vec_new.data(), pG);
2122+
2123+
// temporarily neglect contributions from pG
2124+
matrix_mu[k1_idx + k2_idx * num_k] = dotc(dim, eigvec_k1.data(), 1, vec_new.data(), 1);
20742125
}
2075-
20762126
}
20772127

2128+
// get the hermitian conjugate
2129+
for (uint32_t k2_idx = 0; k2_idx < num_k; k2_idx++) {
2130+
assert(std::abs(matrix_mu[k2_idx + k2_idx * num_k].imag()) < lanczos_precision);
2131+
for (uint32_t k1_idx = k2_idx+1; k1_idx < num_k; k1_idx++) {
2132+
matrix_mu[k1_idx + k2_idx * num_k] = conjugate(matrix_mu[k2_idx + k1_idx * num_k]);
2133+
}
2134+
}
20782135

2079-
2136+
// release memory
2137+
basis_vrnl[sec_new].clear();
2138+
basis_vrnl[sec_new].shrink_to_fit();
20802139
}
20812140

20822141

src/qbasis.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,7 +1316,7 @@ namespace qbasis {
13161316
// ---------------- deprecated --------------------
13171317

13181318

1319-
model(const lattice &latt, const uint32_t &num_secs = 3, const double &fake_pos_ = 100.0);
1319+
model(const lattice &latt, const uint32_t &num_secs = 5, const double &fake_pos_ = 100.0);
13201320

13211321
~model() {}
13221322

@@ -1588,11 +1588,10 @@ namespace qbasis {
15881588
*
15891589
* Each pair denotes the position \f$ r_i \f$ (in cartesin coordinates) and the operator \f$ A_{r_i} \f$.
15901590
*/
1591-
// const std::vector<std::pair<std::vector<double>,mopr<T>>> Ar_list,
1592-
void WannierMat_vrnl(
1591+
void WannierMat_vrnl(const std::vector<std::pair<std::vector<double>,mopr<T>>> &Ar_list,
15931592
const uint32_t &sec_vrnl,
15941593
const std::vector<std::vector<double>> &momenta_list,
1595-
std::vector<std::complex<double>> &matrix_mu_list,
1594+
std::vector<std::complex<double>> &matrix_mu,
15961595
const std::function<MKL_INT(const model<T>&, const uint32_t&)> &locate_state);
15971596

15981597
// later add conserved quantum operators and corresponding quantum numbers?

0 commit comments

Comments
 (0)