@@ -1971,21 +1971,22 @@ namespace qbasis {
1971
1971
lanczos (0 , maxit-1 , maxit, m, dim, HamMat, vec_new.data (), hessenberg, " dnmcs" );
1972
1972
}
1973
1973
1974
- // const std::vector<std::pair<std::vector<double>,mopr<T>>> Ar_list,
1975
1974
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,
1977
1976
const uint32_t &sec_vrnl,
1978
1977
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 ,
1980
1979
const std::function<MKL_INT(const model<T>&, const uint32_t &)> &locate_state)
1981
1980
{
1982
- assert (sec_vrnl < basis_vrnl.size ());
1981
+ assert (sec_vrnl < basis_vrnl.size () - 1 );
1983
1982
1984
1983
MKL_INT dim = dim_vrnl[sec_vrnl];
1985
1984
auto &basis = basis_vrnl[sec_vrnl];
1986
1985
assert (static_cast <MKL_INT>(basis.size ()) == dim);
1987
1986
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;
1989
1990
1990
1991
// first check if eigenstates already built
1991
1992
bool states_built;
@@ -2053,30 +2054,88 @@ namespace qbasis {
2053
2054
}
2054
2055
}
2055
2056
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
2056
2080
std::vector<std::complex<double >> eigvec_k1 (dim);
2057
2081
std::vector<std::complex<double >> eigvec_k2 (dim);
2082
+ std::vector<std::complex<double >> vec_new (dim);
2083
+ T pG;
2058
2084
for (uint32_t k2_idx = 0 ; k2_idx < num_k; k2_idx++) {
2059
2085
// read out phi(k2)
2060
2086
std::string vec_filek2 = " out_Wannier/eigvec_" + std::to_string (k2_idx) + " .dat" ;
2061
2087
int info2 = vec_disk_read (vec_filek2, dim, eigvec_k2.data ());
2062
2088
assert (info2 == 0 );
2063
2089
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
+
2064
2097
for (uint32_t k1_idx = 0 ; k1_idx <= k2_idx; k1_idx++) {
2065
2098
// read out phi(k1)
2066
2099
std::string vec_filek1 = " out_Wannier/eigvec_" + std::to_string (k1_idx) + " .dat" ;
2067
2100
int info1 = vec_disk_read (vec_filek1, dim, eigvec_k1.data ());
2068
2101
assert (info1 == 0 );
2069
2102
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
+
2070
2107
// now need contruct B_{k1-k2}
2108
+ auto Bq = FourierTR (Ar_list, q_transfer);
2071
2109
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;
2072
2113
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;
2073
2120
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 );
2074
2125
}
2075
-
2076
2126
}
2077
2127
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
+ }
2078
2135
2079
-
2136
+ // release memory
2137
+ basis_vrnl[sec_new].clear ();
2138
+ basis_vrnl[sec_new].shrink_to_fit ();
2080
2139
}
2081
2140
2082
2141
0 commit comments