TRIQS/triqs_ctseg 4.0.0
A TRIQS application
Loading...
Searching...
No Matches
invariants.cpp
1// Copyright (c) 2022--present, The Simons Foundation
2// Copyright (c) 2022--present, Max Planck Institute for Polymer Research, Mainz, Germany
3// This file is part of TRIQS/ctseg and is licensed under the terms of GPLv3 or later.
4// SPDX-License-Identifier: GPL-3.0-or-later
5// See LICENSE in the root of this distribution for details.
6
7#include "invariants.hpp"
8#include "logs.hpp"
9#include "util.hpp"
10
11namespace triqs_ctseg {
12
13 void check_invariant(configuration_t const &config, work_data_t const &wdata) {
14 check_segments(config);
15 check_dets(config, wdata);
16 check_jlines(config);
17 }
18
19 void check_segments(configuration_t const &config) {
20 for (auto const &[c, sl] : itertools::enumerate(config.seglists)) {
21 if (not sl.empty()) {
22 for (int i = 0; i < sl.size(); ++i) {
23 if (i != sl.size() - 1) {
24 ALWAYS_EXPECTS((sl[i].tau_cdag > sl[i + 1].tau_c),
25 "Time order error in color {} at position {} in config \n{}", c, i, config);
26 ALWAYS_EXPECTS(not is_cyclic(sl[i]),
27 "Segment in color {} at position {} should not by cyclic in config \n{}", c, i,
28 config); // only last segment can be cyclic
29 }
30 ALWAYS_EXPECTS((sl[i].tau_cdag != sl[i].tau_c),
31 "Degenerate segment in color {} at position {} in config \n{}", c, i, config);
32 }
33 }
34 }
35 LOG("Segments OK.");
36 }
37
38 void check_dets(configuration_t const &config, work_data_t const &wdata) {
39 for (auto bl : range(wdata.dets.size())) {
40 auto const &D = wdata.dets[bl];
41 auto const n_orb = wdata.gf_struct[bl].second;
42 // Times in det must be ordered
43 if (D.size() != 0) {
44 for (int i = 0; i < D.size() - 1; ++i) {
45 ALWAYS_EXPECTS((D.get_x(i).first < D.get_x(i + 1).first),
46 "Det time order error (cdag) in block {} at position {} in config \n{}", bl, i, config);
47 ALWAYS_EXPECTS((D.get_y(i).first < D.get_y(i + 1).first),
48 "Det time order error (c) in block {} at position {} in config \n{}", bl, i, config);
49 }
50 }
51 // Each time in det must correspond to a time in a segment
52 long n_hyb_c = 0, n_hyb_cdag = 0;
53 for (auto c : range(n_orb)) {
54 auto const &sl = config.seglists[wdata.block_to_color(bl, c)];
55 if (not sl.empty()) {
56 long det_index_c = 0, det_index_cdag = 0;
57 for (auto const &seg : sl) {
58 if (not seg.J_c and !is_full_line(seg)) {
59 ALWAYS_EXPECTS(D.size() != 0, "Det error, block {}: there is a hybridized c but det is empty. Config: {}",
60 bl, config);
61 auto det_c_time = [&](long i) { return D.get_y(i).first; };
62 det_index_c = lower_bound(det_c_time, D.size(), seg.tau_c);
63 ALWAYS_EXPECTS(det_c_time(det_index_c) == seg.tau_c,
64 "Det error, block {}: tau_c = {} is not in det! Config: {}", bl, seg.tau_c, config);
65 ++n_hyb_c;
66 }
67 if (not seg.J_cdag and !is_full_line(seg)) {
68 ALWAYS_EXPECTS(D.size() != 0,
69 "Det error, block {}: there is a hybridized cdag but det is empty. Config: {}", bl,
70 config);
71 auto det_cdag_time = [&](long i) { return D.get_x(i).first; };
72 det_index_cdag = lower_bound(det_cdag_time, D.size(), seg.tau_cdag);
73 ALWAYS_EXPECTS(det_cdag_time(det_index_cdag) == seg.tau_cdag,
74 "Det error, block {}: tau_cdag = {} is not in det! Config: {}", bl, seg.tau_cdag, config);
75 ++n_hyb_cdag;
76 }
77 }
78 }
79 }
80 ALWAYS_EXPECTS(n_hyb_c == D.size(), "Det error, block {}: missing {} c times in det. Config: {}", bl,
81 D.size() - n_hyb_c, config);
82 ALWAYS_EXPECTS(n_hyb_cdag == D.size(), "Det error, block {}: missing {} cdag times in det. Config: {}", bl,
83 D.size() - n_hyb_cdag, config);
84 }
85 LOG("Dets OK.");
86 }
87
88 void check_jlines(configuration_t const &config) {
89 // Prepare lists of times in spin lines
90 auto const &jl = config.Jperp_list;
91 if (jl.empty()) return;
92 std::vector<tau_t> Splus, Sminus;
93 for (auto const &[i, line] : itertools::enumerate(config.Jperp_list)) {
94 Splus.push_back(line.tau_Splus);
95 Sminus.push_back(line.tau_Sminus);
96 }
97 std::sort(Splus.begin(), Splus.end());
98 std::sort(Sminus.begin(), Sminus.end());
99
100 for (auto const &[c, sl] : itertools::enumerate(config.seglists)) {
101 auto Splus_ = Splus;
102 auto Sminus_ = Sminus; // will be emptied throughout the checks
103 // Spin lines: each tag has to correpond to the time in a line
104 for (int i = 0; i < sl.size(); ++i) {
105 if (sl[i].J_c) {
106 auto splus_it = std::lower_bound(Splus_.begin(), Splus_.end(), sl[i].tau_c);
107 auto sminus_it = std::lower_bound(Sminus_.begin(), Sminus_.end(), sl[i].tau_c);
108 tau_t tau_plus = tau_t::zero(), tau_minus = tau_t::zero();
109 if (splus_it != Splus_.end()) tau_plus = *splus_it;
110 if (sminus_it != Sminus_.end()) tau_minus = *sminus_it;
111 bool time_in_jlist = sl[i].tau_c == tau_plus or sl[i].tau_c == tau_minus;
112 ALWAYS_EXPECTS(
113 time_in_jlist,
114 "Error: the c in segment at position {} in color {} has a J flag but is not in J list. Config : \n{}", i,
115 c, config);
116 if (sl[i].tau_c == tau_plus)
117 Splus_.erase(splus_it);
118 else
119 Sminus_.erase(sminus_it);
120 }
121 if (sl[i].J_cdag) {
122 auto splus_it = std::lower_bound(Splus_.begin(), Splus_.end(), sl[i].tau_cdag);
123 auto sminus_it = std::lower_bound(Sminus_.begin(), Sminus_.end(), sl[i].tau_cdag);
124 tau_t tau_plus = tau_t::zero(), tau_minus = tau_t::zero();
125 if (splus_it != Splus_.end()) tau_plus = *splus_it;
126 if (sminus_it != Sminus_.end()) tau_minus = *sminus_it;
127 bool time_in_jlist = sl[i].tau_cdag == tau_plus or sl[i].tau_cdag == tau_minus;
128 ALWAYS_EXPECTS(
129 time_in_jlist,
130 "Error: the cdag in segment at position {} in color {} has a J flag but is not in J list. Config : \n{}",
131 i, c, config);
132 if (sl[i].tau_cdag == tau_plus)
133 Splus_.erase(splus_it);
134 else
135 Sminus_.erase(sminus_it);
136 }
137 }
138 ALWAYS_EXPECTS(Splus_.empty() and Sminus_.empty(),
139 "Error: some spin lines do not have corresponding tags on segments. Config: \n{}", config);
140 }
141 LOG("J lines OK.");
142 }
143
144} // namespace triqs_ctseg
static tau_t zero()
$\tau = 0$
Definition tau_t.hpp:70