Xped
Loading...
Searching...
No Matches
Fermion.hpp
Go to the documentation of this file.
1#ifndef XPED_FERMIONSITE_HPP_
2#define XPED_FERMIONSITE_HPP_
3
4#include "fmt/ostream.h"
5#include "fmt/ranges.h"
6#include "fmt/std.h"
7
11#include "Xped/Symmetry/U0.hpp"
13
16
17namespace Xped {
18
19template <typename Symmetry_>
21{
22 using Scalar = double;
23 using Symmetry = Symmetry_;
25 using qType = typename Symmetry::qType;
26
27public:
29 Fermion(bool REMOVE_DOUBLE, bool REMOVE_EMPTY, bool REMOVE_SINGLE, bool CONSIDER_SPIN = true, bool CONSIDER_CHARGE = true);
30
31 OperatorType Id_1s() const { return Id_1s_; }
32 OperatorType F_1s() const { return F_1s_; }
33
34 OperatorType c_1s(SPIN_INDEX sigma) const
35 {
36 if(sigma == SPIN_INDEX::UP) { return cup_1s_; }
37 return cdn_1s_;
38 }
39 OperatorType cdag_1s(SPIN_INDEX sigma) const
40 {
41 if(sigma == SPIN_INDEX::UP) { return cdagup_1s_; }
42 return cdagdn_1s_;
43 }
44
45 OperatorType n_1s() const { return n_1s_; }
46 OperatorType n_1s(SPIN_INDEX sigma) const
47 {
48 if(sigma == SPIN_INDEX::UP) { return nup_1s_; }
49 return ndn_1s_;
50 }
51 OperatorType ns_1s() const { return n_1s() - 2. * d_1s(); }
52 OperatorType nh_1s() const { return 2. * d_1s() - n_1s() + Id_1s(); }
53 OperatorType d_1s() const { return d_1s_; }
54
55 OperatorType Sz_1s() const { return Sz_1s_; }
56 OperatorType Sp_1s() const { return Sp_1s_; }
57 OperatorType Sm_1s() const { return Sm_1s_; }
58
59 OperatorType Tz_1s() const { return 0.5 * (n_1s() - Id_1s()); }
60 OperatorType cc_1s() const { return cc_1s_; }
62
64
65protected:
66 void fill_basis(bool REMOVE_DOUBLE, bool REMOVE_EMPTY, bool REMOVE_SINGLE);
67 void fill_SiteOps(bool REMOVE_DOUBLE, bool REMOVE_EMPTY, bool REMOVE_SINGLE);
68
69 qType getQ(SPIN_INDEX sigma, int Delta) const;
70 qType getQ(SPINOP_LABEL Sa) const;
71
73 std::unordered_map<std::string, std::pair<qType, std::size_t>> labels;
74
75 std::size_t sp_index = 0;
76 std::size_t ch_index = 0;
77
80
81 OperatorType Id_1s_; // identity
82 OperatorType F_1s_; // Fermionic sign
83
84 OperatorType cup_1s_; // annihilation
85 OperatorType cdn_1s_; // annihilation
86
89
90 OperatorType n_1s_; // particle number
91 OperatorType nup_1s_; // particle number
92 OperatorType ndn_1s_; // particle number
93 OperatorType d_1s_; // double occupancy
94
95 OperatorType Sz_1s_; // orbital spin
96 OperatorType Sp_1s_; // orbital spin
97 OperatorType Sm_1s_; // orbital spin
98
99 OperatorType Tz_1s_; // orbital pseude spin
101 OperatorType cdagcdag_1s_; // pairing adjoint
102};
103
104template <typename Symmetry_>
105Fermion<Symmetry_>::Fermion(bool REMOVE_DOUBLE, bool REMOVE_EMPTY, bool REMOVE_SINGLE, bool CONSIDER_SPIN, bool CONSIDER_CHARGE)
106{
107 HAS_SPIN = false;
108 if(CONSIDER_SPIN) {
109 for(std::size_t q = 0; q < Symmetry::Nq; ++q) {
110 if(Symmetry::IS_SPIN[q]) {
111 sp_index = q;
112 HAS_SPIN = true;
113 break;
114 }
115 }
116 }
117
118 HAS_CHARGE = false;
119 if(CONSIDER_CHARGE) {
120 for(std::size_t q = 0; q < Symmetry::Nq; ++q) {
121 if(Symmetry::IS_FERMIONIC[q] or Symmetry::IS_BOSONIC[q]) {
122 ch_index = q;
123 HAS_CHARGE = true;
124 break;
125 }
126 }
127 }
128
129 // create basis for one Fermionic Site
130 fill_basis(REMOVE_DOUBLE, REMOVE_EMPTY, REMOVE_SINGLE);
131 basis_1s_.sort();
132 fill_SiteOps(REMOVE_DOUBLE, REMOVE_EMPTY, REMOVE_SINGLE);
133}
134
135template <typename Symmetry_>
136void Fermion<Symmetry_>::fill_SiteOps(bool REMOVE_DOUBLE, bool REMOVE_EMPTY, bool REMOVE_SINGLE)
137{
138 // create operators for one site
139 Id_1s_ = OperatorType(Symmetry::qvacuum(), basis_1s_, labels);
140 F_1s_ = OperatorType(Symmetry::qvacuum(), basis_1s_, labels);
141
142 cup_1s_ = OperatorType(getQ(SPIN_INDEX::UP, -1), basis_1s_, labels);
143 cup_1s_.setZero();
144 cdn_1s_ = OperatorType(getQ(SPIN_INDEX::DN, -1), basis_1s_, labels);
145 cdn_1s_.setZero();
146
147 cdagup_1s_ = OperatorType(getQ(SPIN_INDEX::UP, +1), basis_1s_, labels);
148 cdagdn_1s_ = OperatorType(getQ(SPIN_INDEX::DN, +1), basis_1s_, labels);
149
150 n_1s_ = OperatorType(Symmetry::qvacuum(), basis_1s_, labels);
151 nup_1s_ = OperatorType(Symmetry::qvacuum(), basis_1s_, labels);
152 ndn_1s_ = OperatorType(Symmetry::qvacuum(), basis_1s_, labels);
153 d_1s_ = OperatorType(Symmetry::qvacuum(), basis_1s_, labels);
154
155 Sz_1s_ = OperatorType(getQ(SPINOP_LABEL::SZ), basis_1s_, labels);
156 Sz_1s_.setZero();
157 Sp_1s_ = OperatorType(getQ(SPINOP_LABEL::SP), basis_1s_, labels);
158 Sp_1s_.setZero();
159 Sm_1s_ = OperatorType(getQ(SPINOP_LABEL::SM), basis_1s_, labels);
160 Sm_1s_.setZero();
161
162 cc_1s_ = OperatorType(getQ(SPIN_INDEX::UPDN, -1), basis_1s_, labels);
163 cdagcdag_1s_ = OperatorType(getQ(SPIN_INDEX::UPDN, +1), basis_1s_, labels);
164
165 Id_1s_.setIdentity();
166
167 F_1s_.setZero();
168
169 if(!REMOVE_EMPTY) F_1s_("empty", "empty") = 1.;
170 if(!REMOVE_DOUBLE) F_1s_("double", "double") = 1.;
171 if(!REMOVE_SINGLE) {
172 F_1s_("up", "up") = -1.;
173 F_1s_("dn", "dn") = -1.;
174 }
175
176 if(!REMOVE_EMPTY and !REMOVE_SINGLE) { cup_1s_("empty", "up") = 1.; }
177 if(!REMOVE_DOUBLE and !REMOVE_SINGLE) { cup_1s_("dn", "double") = 1.; }
178
179 if(!REMOVE_EMPTY and !REMOVE_SINGLE) { cdn_1s_("empty", "dn") = 1.; }
180 if(!REMOVE_EMPTY and !REMOVE_SINGLE) { cdn_1s_("up", "double") = -1.; }
181
182 cdagup_1s_ = cup_1s_.adjoint();
183 cdagdn_1s_ = cdn_1s_.adjoint();
184
185 // std::cout << std::fixed << cdagup_1s_ << std::endl
186 // << cdagup_1s_.plain()[0] << std::endl
187 // << cup_1s_ << std::endl
188 // << cup_1s_.plain()[0] << std::endl;
189
190 nup_1s_ = cdagup_1s_ * cup_1s_;
191 ndn_1s_ = cdagdn_1s_ * cdn_1s_;
192 n_1s_ = nup_1s_ + ndn_1s_;
193
194 d_1s_.setZero();
195 if(!REMOVE_DOUBLE) d_1s_("double", "double") = 1.;
196
197 cc_1s_ = cdn_1s_ * cup_1s_;
198 cdagcdag_1s_ = cc_1s_.adjoint();
199
200 if(!REMOVE_SINGLE) {
201 Sz_1s_ = 0.5 * (nup_1s_ - ndn_1s_);
202 Sp_1s_ = cup_1s_.adjoint() * cdn_1s_;
203 Sm_1s_ = Sp_1s_.adjoint();
204 }
205}
206
207template <typename Symmetry_>
208void Fermion<Symmetry_>::fill_basis(bool REMOVE_DOUBLE, bool REMOVE_EMPTY, bool REMOVE_SINGLE)
209{
210 if constexpr(Symmetry::ALL_IS_TRIVIAL) // U0
211 {
212 qType Q = Symmetry::qvacuum();
213 std::size_t dim = 0;
214 if(not REMOVE_EMPTY) { labels.insert(std::make_pair("empty", std::make_pair(Q, dim++))); }
215 if(not REMOVE_SINGLE) {
216 labels.insert(std::make_pair("up", std::make_pair(Q, dim++)));
217 labels.insert(std::make_pair("dn", std::make_pair(Q, dim++)));
218 }
219 if(not REMOVE_DOUBLE) { labels.insert(std::make_pair("double", std::make_pair(Q, dim++))); }
220 this->basis_1s_.push_back(Q, dim);
221 return;
222 } else {
223 if(not HAS_SPIN and HAS_CHARGE) {
224 qType Q = Symmetry::qvacuum();
225 if(not REMOVE_EMPTY) {
226 this->basis_1s_.push_back(Q, 1);
227 labels.insert(std::make_pair("empty", std::make_pair(Q, 0)));
228 }
229 if(not REMOVE_DOUBLE) {
230 std::size_t dim = (Symmetry::MOD_N[ch_index] == 2) ? 1 : 0;
231 Q[ch_index] = Symmetry::IS_MODULAR[ch_index] ? util::constFct::posmod(2, Symmetry::MOD_N[ch_index]) : 2;
232 this->basis_1s_.push_back(Q, 1);
233 labels.insert(std::make_pair("double", std::make_pair(Q, dim)));
234 }
235 if(not REMOVE_SINGLE) {
236 Q[ch_index] = 1;
237 this->basis_1s_.push_back(Q, 2);
238 labels.insert(std::make_pair("up", std::make_pair(Q, 0)));
239 labels.insert(std::make_pair("dn", std::make_pair(Q, 1)));
240 }
241 } else if(HAS_SPIN and not HAS_CHARGE) {
242 qType Q = Symmetry::qvacuum();
243 std::size_t dim = 0;
244 if(not REMOVE_EMPTY) { labels.insert(std::make_pair("empty", std::make_pair(Q, dim++))); }
245 if(not REMOVE_DOUBLE) { labels.insert(std::make_pair("double", std::make_pair(Q, dim++))); }
246 this->basis_1s_.push_back(Q, dim);
247 if(not REMOVE_SINGLE) {
248 Q[sp_index] = 1;
249 this->basis_1s_.push_back(Q, 1);
250 labels.insert(std::make_pair("up", std::make_pair(Q, 0)));
251 Q[sp_index] = Symmetry::IS_MODULAR[sp_index] ? util::constFct::posmod(-1, Symmetry::MOD_N[sp_index]) : -1;
252 this->basis_1s_.push_back(Q, 1);
253 labels.insert(std::make_pair("dn", std::make_pair(Q, 0)));
254 }
255 } else {
256 qType Q = Symmetry::qvacuum();
257 if(not REMOVE_EMPTY) {
258 this->basis_1s_.push_back(Q, 1);
259 labels.insert(std::make_pair("empty", std::make_pair(Q, 0)));
260 }
261 if(not REMOVE_DOUBLE) {
262 std::size_t dim = (Symmetry::MOD_N[ch_index] == 2) ? 1 : 0;
263 Q[ch_index] = Symmetry::IS_MODULAR[ch_index] ? util::constFct::posmod(2, Symmetry::MOD_N[ch_index]) : 2;
264 this->basis_1s_.push_back(Q, 1);
265 labels.insert(std::make_pair("double", std::make_pair(Q, dim)));
266 }
267 if(not REMOVE_SINGLE) {
268 Q[ch_index] = 1;
269 Q[sp_index] = 1;
270 this->basis_1s_.push_back(Q, 1);
271 labels.insert(std::make_pair("up", std::make_pair(Q, 0)));
272 Q[sp_index] = Symmetry::IS_MODULAR[sp_index] ? util::constFct::posmod(-1, Symmetry::MOD_N[sp_index]) : -1;
273 this->basis_1s_.push_back(Q, 1);
274 labels.insert(std::make_pair("dn", std::make_pair(Q, 0)));
275 }
276 }
277 }
278}
279
280template <typename Symmetry_>
281typename Symmetry_::qType Fermion<Symmetry_>::getQ(SPIN_INDEX sigma, int Delta) const
282{
283 auto Q = Symmetry::qvacuum();
284 if constexpr(Symmetry::ALL_IS_TRIVIAL) {
285 return Q;
286 } else {
287 if(not HAS_SPIN and HAS_CHARGE) {
288 if(sigma == SPIN_INDEX::UP or sigma == SPIN_INDEX::DN) {
289 Q[ch_index] = Symmetry::IS_MODULAR[ch_index] ? util::constFct::posmod(Delta, Symmetry::MOD_N[ch_index]) : Delta;
290 return Q;
291 }
292 if(sigma == SPIN_INDEX::UPDN) {
293 Q[ch_index] = Symmetry::IS_MODULAR[ch_index] ? util::constFct::posmod(2 * Delta, Symmetry::MOD_N[ch_index]) : 2 * Delta;
294 return Q;
295 }
296 return Q;
297 } else if(HAS_SPIN and not HAS_CHARGE) {
298 if(sigma == SPIN_INDEX::UP) {
299 Q[sp_index] = Symmetry::IS_MODULAR[sp_index] ? util::constFct::posmod(Delta, Symmetry::MOD_N[sp_index]) : Delta;
300 return Q;
301 }
302 if(sigma == SPIN_INDEX::DN) {
303 Q[sp_index] = Symmetry::IS_MODULAR[sp_index] ? util::constFct::posmod(-Delta, Symmetry::MOD_N[sp_index]) : -Delta;
304 return Q;
305 }
306 return Q;
307 } else {
308 if(sigma == SPIN_INDEX::UP) {
309 Q[sp_index] = Symmetry::IS_MODULAR[sp_index] ? util::constFct::posmod(Delta, Symmetry::MOD_N[sp_index]) : Delta;
310 Q[ch_index] = Symmetry::IS_MODULAR[ch_index] ? util::constFct::posmod(Delta, Symmetry::MOD_N[ch_index]) : Delta;
311 return Q;
312 }
313 if(sigma == SPIN_INDEX::DN) {
314 Q[sp_index] = Symmetry::IS_MODULAR[sp_index] ? util::constFct::posmod(-Delta, Symmetry::MOD_N[sp_index]) : -Delta;
315 Q[ch_index] = Symmetry::IS_MODULAR[ch_index] ? util::constFct::posmod(Delta, Symmetry::MOD_N[ch_index]) : Delta;
316 return Q;
317 }
318 if(sigma == SPIN_INDEX::UPDN) {
319 Q[ch_index] = Symmetry::IS_MODULAR[ch_index] ? util::constFct::posmod(2 * Delta, Symmetry::MOD_N[ch_index]) : 2 * Delta;
320 return Q;
321 }
322 return Q;
323 }
324 }
325}
326
327template <typename Symmetry_>
328typename Symmetry_::qType Fermion<Symmetry_>::getQ(SPINOP_LABEL Sa) const
329{
330 auto Q = Symmetry::qvacuum();
331 if constexpr(Symmetry::ALL_IS_TRIVIAL) {
332 return Q;
333 } else {
334 if(HAS_SPIN) {
335 assert(Sa != SPINOP_LABEL::SX and Sa != SPINOP_LABEL::iSY and "Sx and Sy break the U1 spin symmetry.");
336 if(Sa == SPINOP_LABEL::SZ) {
337 return Q;
338 } else if(Sa == SPINOP_LABEL::SP) {
339 Q[sp_index] = Symmetry::IS_MODULAR[sp_index] ? util::constFct::posmod(2, Symmetry::MOD_N[sp_index]) : 2;
340 } else if(Sa == SPINOP_LABEL::SM) {
341 Q[sp_index] = Symmetry::IS_MODULAR[sp_index] ? util::constFct::posmod(-2, Symmetry::MOD_N[sp_index]) : -2;
342 }
343 return Q;
344 }
345 }
346 return Q;
347}
348
349} // namespace Xped
350#endif // FERMIONSITE_H_
Definition: Fermion.hpp:21
std::size_t sp_index
Definition: Fermion.hpp:75
OperatorType Sm_1s_
Definition: Fermion.hpp:97
OperatorType ns_1s() const
Definition: Fermion.hpp:51
std::size_t ch_index
Definition: Fermion.hpp:76
OperatorType d_1s_
Definition: Fermion.hpp:93
OperatorType Sz_1s_
Definition: Fermion.hpp:95
OperatorType cdagcdag_1s() const
Definition: Fermion.hpp:61
OperatorType cdagup_1s_
Definition: Fermion.hpp:87
OperatorType cup_1s_
Definition: Fermion.hpp:84
OperatorType n_1s_
Definition: Fermion.hpp:90
bool HAS_SPIN
Definition: Fermion.hpp:78
OperatorType Id_1s() const
Definition: Fermion.hpp:31
bool HAS_CHARGE
Definition: Fermion.hpp:79
Fermion()
Definition: Fermion.hpp:28
OperatorType cdagcdag_1s_
Definition: Fermion.hpp:101
qType getQ(SPIN_INDEX sigma, int Delta) const
Definition: Fermion.hpp:281
OperatorType n_1s(SPIN_INDEX sigma) const
Definition: Fermion.hpp:46
OperatorType Sm_1s() const
Definition: Fermion.hpp:57
OperatorType Id_1s_
Definition: Fermion.hpp:81
OperatorType Tz_1s_
Definition: Fermion.hpp:99
OperatorType c_1s(SPIN_INDEX sigma) const
Definition: Fermion.hpp:34
OperatorType Sz_1s() const
Definition: Fermion.hpp:55
OperatorType nh_1s() const
Definition: Fermion.hpp:52
OperatorType Sp_1s_
Definition: Fermion.hpp:96
OperatorType d_1s() const
Definition: Fermion.hpp:53
OperatorType cdagdn_1s_
Definition: Fermion.hpp:88
OperatorType Tz_1s() const
Definition: Fermion.hpp:59
OperatorType n_1s() const
Definition: Fermion.hpp:45
OperatorType Sp_1s() const
Definition: Fermion.hpp:56
Qbasis< Symmetry, 1 > basis_1s_
Definition: Fermion.hpp:72
qType getQ(SPINOP_LABEL Sa) const
Definition: Fermion.hpp:328
OperatorType ndn_1s_
Definition: Fermion.hpp:92
void fill_SiteOps(bool REMOVE_DOUBLE, bool REMOVE_EMPTY, bool REMOVE_SINGLE)
Definition: Fermion.hpp:136
std::unordered_map< std::string, std::pair< qType, std::size_t > > labels
Definition: Fermion.hpp:73
OperatorType F_1s() const
Definition: Fermion.hpp:32
OperatorType cc_1s() const
Definition: Fermion.hpp:60
void fill_basis(bool REMOVE_DOUBLE, bool REMOVE_EMPTY, bool REMOVE_SINGLE)
Definition: Fermion.hpp:208
OperatorType cdag_1s(SPIN_INDEX sigma) const
Definition: Fermion.hpp:39
Fermion(bool REMOVE_DOUBLE, bool REMOVE_EMPTY, bool REMOVE_SINGLE, bool CONSIDER_SPIN=true, bool CONSIDER_CHARGE=true)
Definition: Fermion.hpp:105
OperatorType cdn_1s_
Definition: Fermion.hpp:85
OperatorType F_1s_
Definition: Fermion.hpp:82
OperatorType cc_1s_
Definition: Fermion.hpp:100
OperatorType nup_1s_
Definition: Fermion.hpp:91
Qbasis< Symmetry, 1 > basis_1s() const
Definition: Fermion.hpp:63
Definition: Qbasis.hpp:39
constexpr int posmod(int x)
Definition: Constfct.hpp:46
Definition: bench.cpp:62