Skip to content

Commit 6de7501

Browse files
committed
Make density-matrix trace checks optional
1 parent 95fd3de commit 6de7501

5 files changed

Lines changed: 25 additions & 15 deletions

File tree

c++/dmnrg.hpp

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -50,15 +50,15 @@ auto init_rho(const Step &step, const DiagInfo<S> &diag_in, const Symmetry<S> *S
5050
const auto Z = grand_canonical_Z(step.scT(), diag_in, mult);
5151
for (const auto &[I, eig] : diag_in)
5252
rho[I] = eig.diagonal_exp(step.scT()) / Z;
53-
check_trace_rho(rho, mult);
53+
if (P.checkrho) check_trace_rho(rho, mult);
5454
return rho;
5555
}
5656
const auto diag = Sym->project(diag_in, P.project);
5757
DensMatElements<S> rho;
5858
const auto Z = grand_canonical_Z(step.scT(), diag, mult);
5959
for (const auto &[I, eig] : diag)
6060
rho[I] = eig.diagonal_exp(step.scT()) / Z;
61-
check_trace_rho(rho, mult);
61+
if (P.checkrho) check_trace_rho(rho, mult);
6262
return rho;
6363
}
6464

@@ -133,13 +133,13 @@ template<scalar S>
133133
void calc_densitymatrix(DensMatElements<S> &rho, const BackiterStore &store_all, const Symmetry<S> *Sym,
134134
MemTime &mt, const Params &P, const std::string filename = fn_rho) {
135135
if (P.resume && already_computed(filename, P)) return;
136-
check_trace_rho(rho, Sym->multfnc()); // Must be 1.
136+
if (P.checkrho) check_trace_rho(rho, Sym->multfnc()); // Must be 1.
137137
const auto section_timing = mt.time_it("DM");
138138
for (size_t N = P.Nmax - 1; N > P.Ninit; N--) {
139139
std::cout << "[DM] " << N << std::endl;
140140
const DiagInfo<S> diag_loaded(N, P);
141141
auto rhoPrev = calc_densitymatrix_iterN(diag_loaded, rho, N, store_all, Sym, P); // need store_all for backiteration!
142-
check_trace_rho(rhoPrev, Sym->multfnc()); // Make sure rho is normalized to 1.
142+
if (P.checkrho) check_trace_rho(rhoPrev, Sym->multfnc()); // Make sure rho is normalized to 1.
143143
rhoPrev.save(N-1, P, filename);
144144
rho.swap(rhoPrev);
145145
}
@@ -157,15 +157,15 @@ void calc_densitymatrix(DensMatElements<S> &rho, const BackiterStore &store_all,
157157
// H. Zhang, X. C. Xie, Q. Sun, Phys. Rev. B 82, 075111 (2010)
158158
template<scalar S, typename MF>
159159
DensMatElements<S> init_rho_FDM(const size_t N, const ThermoStore<S> &store, const Stats<S> &stats,
160-
MF mult, const double T) {
160+
MF mult, const double T, const bool checkrho) {
161161
DensMatElements<S> rhoFDM;
162162
for (const auto &[I, ds] : store[N]) {
163163
rhoFDM[I] = zero_matrix<S>(ds.max());
164164
if (stats.ZnDNd[N] != 0.0)
165165
for (const auto i: ds.all())
166166
rhoFDM[I](i, i) = exp(-ds.eig.values.abs_zero(i) / T) * stats.wn[N] / stats.ZnDNd[N];
167167
}
168-
if (stats.wn[N] != 0.0) { // note: wn \propto ZnDNd, so this is the same condition as above
168+
if (checkrho && stats.wn[N] != 0.0) { // note: wn \propto ZnDNd, so this is the same condition as above
169169
// Trace should be equal to the total weight of the shell-N contribution to the FDM.
170170
const auto tr = rhoFDM.trace(mult);
171171
const auto diff = (tr - stats.wn[N]) / stats.wn[N]; // relative error
@@ -184,7 +184,7 @@ auto calc_fulldensitymatrix_iterN(const Step &step, // only required for step::l
184184
DensMatElements<S> rhoDD;
185185
DensMatElements<S> rhoFDMPrev;
186186
if (!step.last(N))
187-
rhoDD = init_rho_FDM(N, store, stats, Sym->multfnc(), P.T); // store here!
187+
rhoDD = init_rho_FDM(N, store, stats, Sym->multfnc(), P.T, P.checkrho); // store here!
188188
for (const auto &[I, ds] : store_all[N - 1]) { // loop over all subspaces at *previous* iteration, hence store_all here
189189
const auto subs = Sym->new_subspaces(I);
190190
const auto dim = ds.kept();
@@ -218,11 +218,13 @@ void calc_fulldensitymatrix(const Step &step, DensMatElements<S> &rhoFDM, const
218218
std::cout << "[FDM] " << N << std::endl;
219219
const DiagInfo<S> diag_loaded(N, P); // = load_and_project(N, Sym, P);
220220
auto rhoFDMPrev = calc_fulldensitymatrix_iterN(step, diag_loaded, rhoFDM, N, store, store_all, stats, Sym, P);
221-
const auto tr = rhoFDMPrev.trace(Sym->multfnc());
222-
const auto expected = std::accumulate(stats.wn.begin() + N, stats.wn.begin() + P.Nmax, 0.0);
223-
const auto diff = (tr - expected) / expected;
224-
nrglog('w', "tr[rhoFDM(" << N << ")]=" << tr << " sum(wn)=" << expected << " diff=" << diff);
225-
my_assert(num_equal(diff, 0.0));
221+
if (P.checkrho) {
222+
const auto tr = rhoFDMPrev.trace(Sym->multfnc());
223+
const auto expected = std::accumulate(stats.wn.begin() + N, stats.wn.begin() + P.Nmax, 0.0);
224+
const auto diff = (tr - expected) / expected;
225+
nrglog('w', "tr[rhoFDM(" << N << ")]=" << tr << " sum(wn)=" << expected << " diff=" << diff);
226+
my_assert(num_equal(diff, 0.0));
227+
}
226228
rhoFDMPrev.save(N-1, P, filename);
227229
rhoFDM.swap(rhoFDMPrev);
228230
}

c++/measurements.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ void calculate_spectral_and_expv_impl(const Step &step,
209209
if (step.dmnrg()) {
210210
if (P.need_rho()) {
211211
rho.load(step.ndx(), P, fn_rho, P.removefiles);
212-
check_trace_rho(rho, Sym->multfnc()); // Check if Tr[rho]=1, i.e. the normalization
212+
if (P.checkrho) check_trace_rho(rho, Sym->multfnc()); // Check if Tr[rho]=1, i.e. the normalization
213213
}
214214
if (P.need_rhoFDM())
215215
rhoFDM.load(step.ndx(), P, fn_rhoFDM, P.removefiles);

c++/nrg-general.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ template <scalar S> class NRG_calculation {
134134
if (P.logletter('w'))
135135
report_ZnD(stats, P);
136136
fdm_thermodynamics(store, stats, Sym.get(), P.T);
137-
auto rhoFDM = init_rho_FDM(step.lastndx(), store, stats, Sym->multfnc(), P.T);
137+
auto rhoFDM = init_rho_FDM(step.lastndx(), store, stats, Sym->multfnc(), P.T, P.checkrho);
138138
rhoFDM.save(step.lastndx(), P, fn_rhoFDM);
139139
calc_fulldensitymatrix(step, rhoFDM, store, store_all, stats, Sym.get(), mt, P);
140140
}

c++/params.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,11 @@ enum class RUNTYPE { NRG, DMNRG }; // First or second sweep? Used in class Step.
3434

3535
inline const auto fn_rho {"rho"s};
3636
inline const auto fn_rhoFDM {"rhofdm"s};
37+
#ifdef NDEBUG
38+
inline const auto default_checkrho {"false"s};
39+
#else
40+
inline const auto default_checkrho {"true"s};
41+
#endif
3742

3843
// Base class for parameter containers
3944
// XXX C++20: std::string may be constexpr
@@ -273,6 +278,9 @@ class Params {
273278
// Automatically enabled when needed (DMNRG, CFS, FDM).
274279
param<bool> dm{"dm", "Compute density matrixes?", "false", all}; // N
275280

281+
// Check density-matrix trace normalization. Enabled by default in debug builds, disabled in release builds.
282+
param<bool> checkrho{"checkrho", "Check density-matrix trace normalization", default_checkrho, all}; // N
283+
276284
// **************
277285
// Frequency mesh
278286
param<double> broaden_max{"broaden_max", "Broadening mesh maximum frequency", "10", all}; // N

test/unit/test_clean/test_clean.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ TEST(Clean, H) { // NOLINT
7373

7474
calc_ZnD(store, stats, Sym, P);
7575
fdm_thermodynamics(store, stats, Sym, P.T);
76-
auto rhoFDM = init_rho_FDM(step.lastndx(), store, stats, Sym->multfnc(), P.T);
76+
auto rhoFDM = init_rho_FDM(step.lastndx(), store, stats, Sym->multfnc(), P.T, P.checkrho);
7777
rhoFDM.save(step.lastndx(), P, fn_rhoFDM);
7878
calc_fulldensitymatrix(step, rhoFDM, store, store_all, stats, Sym, mt, P);
7979

0 commit comments

Comments
 (0)