TRIQS/triqs_cthyb 4.0.0
A TRIQS application
Loading...
Searching...
No Matches
density_matrix.cpp
1/*******************************************************************************
2 *
3 * TRIQS: a Toolbox for Research in Interacting Quantum Systems
4 *
5 * Copyright (C) 2014, P. Seth, I. Krivenko, M. Ferrero and O. Parcollet
6 *
7 * TRIQS is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later
10 * version.
11 *
12 * TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15 * details.
16 *
17 * You should have received a copy of the GNU General Public License along with
18 * TRIQS. If not, see <http://www.gnu.org/licenses/>.
19 *
20 ******************************************************************************/
21#include "./density_matrix.hpp"
22#include <mpi/vector.hpp>
23
24#include <iomanip>
25
26namespace triqs_cthyb {
27
28 measure_density_matrix::measure_density_matrix(qmc_data const &data, std::vector<matrix_t> &density_matrix) : data(data), block_dm(density_matrix) {
29 block_dm.resize(data.imp_trace.get_density_matrix().size());
30 for (int i = 0; i < block_dm.size(); ++i) {
31 block_dm[i] = data.imp_trace.get_density_matrix()[i].mat;
32 block_dm[i]() = 0;
33 }
34 }
35 // --------------------
36
37 void measure_density_matrix::accumulate(mc_weight_t s) {
38 // we assume here that we are in "Norm" mode, i.e. qmc weight is norm, not trace
39
40 // We need to recompute since the density_matrix in the trace is changed at each computatation,
41 // in particular at the last failed attempt.
42 // So we need to compute it, without any Yee threshold.
43 data.imp_trace.compute();
44 z += s * data.atomic_reweighting;
45 s /= data.atomic_weight; // accumulate matrix / norm since weight is norm * det
46
47 // Careful: there is no reweighting factor here!
48 int size = block_dm.size();
49 for (int i = 0; i < size; ++i)
50 if (data.imp_trace.get_density_matrix()[i].is_valid) { block_dm[i] += s * data.imp_trace.get_density_matrix()[i].mat; }
51 }
52
53 // ---------------------------------------------
54
55 void measure_density_matrix::collect_results(mpi::communicator const &c) {
56
57 z = mpi::all_reduce(z, c);
58 block_dm = mpi::all_reduce(block_dm, c);
59 for (auto &b : block_dm){
60 // Normalize
61 b /= real(z);
62
63 // Enforce hermiticity
64 b = make_regular(0.5*(b + dagger(b)));
65 }
66
67 if (c.rank() != 0) return;
68
69 // Check: the trace of the density matrix must be 1 by construction
70 h_scalar_t tr = 0;
71 for (auto &b : block_dm) tr += trace(b);
72 if (std::abs(tr - 1) > 0.0001) TRIQS_RUNTIME_ERROR << "Trace of the density matrix is " << tr << " instead of 1";
73 if (std::abs(tr - 1) > 1.e-10)
74 std::cerr << "Warning :: Trace of the density matrix is " << std::setprecision(13) << tr << std::setprecision(6) << " instead of 1"
75 << std::endl;
76
77 }
78}