VMPS++
Loading...
Searching...
No Matches
FermionSite.h
Go to the documentation of this file.
1#ifndef FERMIONSITE_H_
2#define FERMIONSITE_H_
3
4#include "symmetry/U0.h"
5#include "symmetry/ZN.h"
6
13
14template <typename Symmetry_>
16{
17 typedef double Scalar;
18 typedef Symmetry_ Symmetry;
21
22public:
23
25 FermionSite (bool REMOVE_DOUBLE, bool REMOVE_EMPTY, bool REMOVE_UP, bool REMOVE_DN, int mfactor_input=1, int k_input=0);
26
27 OperatorType Id_1s() const {return Id_1s_;}
28 OperatorType F_1s() const {return F_1s_;}
29
30 OperatorType c_1s(SPIN_INDEX sigma) const { if (sigma == UP) {return cup_1s_;} return cdn_1s_;}
31 OperatorType cdag_1s(SPIN_INDEX sigma) const { if (sigma == UP) {return cdagup_1s_;} return cdagdn_1s_;}
32
33 OperatorType n_1s() const {return n_1s_;}
34 OperatorType n_1s(SPIN_INDEX sigma) const { if (sigma == UP) {return nup_1s_;} return ndn_1s_;}
35 OperatorType ns_1s() const {return n_1s()-2.*d_1s();}
36 OperatorType nh_1s() const {return 2.*d_1s()-n_1s()+Id_1s();}
37 OperatorType d_1s() const {return d_1s_;}
38
39 OperatorType Sz_1s() const {return Sz_1s_;}
40 OperatorType Sp_1s() const {return Sp_1s_;}
41 OperatorType Sm_1s() const {return Sm_1s_;}
43
44 OperatorType Tz_1s() const {return 0.5*(n_1s()-Id_1s());}
45 OperatorType cc_1s() const {return cc_1s_;}
47
49
50protected:
51
52 int mfactor = 1;
53 int k = 0;
54
55 void fill_basis (bool REMOVE_DOUBLE, bool REMOVE_EMPTY, bool REMOVE_UP, bool REMOVE_DN);
56 void fill_SiteOps (bool REMOVE_DOUBLE, bool REMOVE_EMPTY, bool REMOVE_UP, bool REMOVE_DN);
57
58 typename Symmetry_::qType getQ (SPIN_INDEX sigma, int Delta) const;
59 typename Symmetry_::qType getQ (SPINOP_LABEL Sa) const;
60
62
63 OperatorType Id_1s_; //identity
64 OperatorType F_1s_; //Fermionic sign
65
66 OperatorType cup_1s_; //annihilation
67 OperatorType cdn_1s_; //annihilation
68
71
72 OperatorType n_1s_; //particle number
73 OperatorType nup_1s_; //particle number
74 OperatorType ndn_1s_; //particle number
75 OperatorType d_1s_; //double occupancy
76
77 OperatorType Sz_1s_; //orbital spin
78 OperatorType Sp_1s_; //orbital spin
79 OperatorType Sm_1s_; //orbital spin
81
82 OperatorType Tz_1s_; //orbital pseude spin
84 OperatorType cdagcdag_1s_; //pairing adjoint
85};
86
87template<typename Symmetry_>
89FermionSite (bool REMOVE_DOUBLE, bool REMOVE_EMPTY, bool REMOVE_UP, bool REMOVE_DN, int mfactor_input, int k_input)
90:mfactor(mfactor_input), k(k_input)
91{
92 //create basis for one Fermionic Site
93 fill_basis(REMOVE_DOUBLE, REMOVE_EMPTY, REMOVE_UP, REMOVE_DN);
94 //cout << "single site basis" << endl << this->basis_1s_ << endl;
95
96 fill_SiteOps(REMOVE_DOUBLE, REMOVE_EMPTY, REMOVE_UP, REMOVE_DN);
97 //cout << "fill_SiteOps done!" << endl;
98}
99
100template <typename Symmetry_>
102fill_SiteOps (bool REMOVE_DOUBLE, bool REMOVE_EMPTY, bool REMOVE_UP, bool REMOVE_DN)
103{
104 // create operators for one site
105 Id_1s_ = OperatorType(Symmetry::qvacuum(),basis_1s_);
106 F_1s_ = OperatorType(Symmetry::qvacuum(),basis_1s_);
107
108 cup_1s_ = OperatorType(getQ(UP,-1),basis_1s_);
109 cdn_1s_ = OperatorType(getQ(DN,-1),basis_1s_);
110 //cout << getQ(UP,-1) << "\t" << getQ(DN,-1) << endl;
111
112 cdagup_1s_ = OperatorType(getQ(UP,+1),basis_1s_);
113 cdagdn_1s_ = OperatorType(getQ(DN,+1),basis_1s_);
114 //cout << getQ(UP,+1) << "\t" << getQ(DN,+1) << endl;
115
116 n_1s_ = OperatorType(Symmetry::qvacuum(),basis_1s_);
117 nup_1s_ = OperatorType(Symmetry::qvacuum(),basis_1s_);
118 ndn_1s_ = OperatorType(Symmetry::qvacuum(),basis_1s_);
119 d_1s_ = OperatorType(Symmetry::qvacuum(),basis_1s_);
120
121 Sz_1s_ = OperatorType(getQ(SZ),basis_1s_);
122 Sp_1s_ = OperatorType(getQ(SP),basis_1s_);
123 Sm_1s_ = OperatorType(getQ(SM),basis_1s_);
124 exp_ipiSz_1s_= ComplexOperatorType(getQ(SZ),basis_1s_);
125
126 cc_1s_ = OperatorType(getQ(UPDN,-1),basis_1s_);
127 cdagcdag_1s_ = OperatorType(getQ(UPDN,+1),basis_1s_);
128 //cout << getQ(UPDN,-1) << "\t" << getQ(UPDN,+1) << endl;
129
130 if (!REMOVE_EMPTY) Id_1s_("empty", "empty") = 1.;
131 if (!REMOVE_DOUBLE) Id_1s_("double", "double") = 1.;
132 if (!REMOVE_UP) Id_1s_("up","up") = 1.;
133 if (!REMOVE_DN) Id_1s_("dn","dn") = 1.;
134
135 if (!REMOVE_EMPTY) F_1s_("empty", "empty") = 1.;
136 if (!REMOVE_DOUBLE) F_1s_("double", "double") = 1.;
137 if (!REMOVE_UP) F_1s_("up","up") = -1.;
138 if (!REMOVE_DN) F_1s_("dn","dn") = -1.;
139
140 if (!REMOVE_EMPTY and !REMOVE_UP)
141 {
142 cup_1s_("empty","up") = 1.;
143 cdagup_1s_("up","empty") = 1.;
144 }
145 if (!REMOVE_EMPTY and !REMOVE_DN)
146 {
147 cup_1s_("dn","double") = 1.;
148 cdagup_1s_("double","dn") = 1.;
149 }
150
151 if (!REMOVE_EMPTY and !REMOVE_DN)
152 {
153 cdn_1s_("empty","dn") = 1.;
154 cdagdn_1s_("dn","empty") = 1.;
155 }
156 if (!REMOVE_DOUBLE and !REMOVE_UP)
157 {
158 cdn_1s_("up","double") = -1.;
159 cdagdn_1s_("double","up") = -1.;
160 }
161
162 //nup_1s_ = cup_1s_.adjoint() * cup_1s_;
163 //ndn_1s_ = cdn_1s_.adjoint() * cdn_1s_;
164
165 if (!REMOVE_UP)
166 {
167 nup_1s_("up","up") = 1.;
168 }
169 if (!REMOVE_DN)
170 {
171 ndn_1s_("dn","dn") = 1.;
172 }
173 if (!REMOVE_DOUBLE)
174 {
175 nup_1s_("double","double") = 1.;
176 ndn_1s_("double","double") = 1.;
177 }
178
179 n_1s_ = nup_1s_+ndn_1s_;
180
181 if (!REMOVE_DOUBLE) d_1s_("double","double") = 1.;
182
183 if (!REMOVE_EMPTY and !REMOVE_DOUBLE)
184 {
185 cc_1s_("empty","double") = +1.; // c_DN c_UP
186 cdagcdag_1s_("double","empty") = +1.; // c_UP† c_DN†
187 }
188
189// lout << "cdagcdag_1s_=" << MatrixXd(cdagcdag_1s_.template plain<double>().data)<< endl;
190// lout << "cc_1s_=" << MatrixXd(cc_1s_.template plain<double>().data)<< endl;
191
192 //cc_1s_ = cdn_1s_ * cup_1s_; //The sign convention corresponds to c_DN c_UP
193 //cdagcdag_1s_ = cc_1s_.adjoint(); //The sign convention corresponds to (c_DN c_UP)†=c_UP† c_DN†
194
195 if (!REMOVE_UP and !REMOVE_DN)
196 {
197 Sz_1s_ = 0.5*(nup_1s_-ndn_1s_);
198 Sp_1s_ = cup_1s_.adjoint() * cdn_1s_;
199 Sm_1s_ = Sp_1s_.adjoint();
200
201 exp_ipiSz_1s_("up","up") = 1.i;
202 exp_ipiSz_1s_("dn","dn") = -1.i;
203 }
204
205 if (!REMOVE_EMPTY) exp_ipiSz_1s_("empty","empty") = 1.+0.i;
206 if (!REMOVE_DOUBLE) exp_ipiSz_1s_("double","double") = 1.+0.i;
207
208// cout << "cup_1s_=" << endl << MatrixXcd(exp_ipiSz_1s_.template plain<complex<double> >().data) << endl;
209// cout << "cup_1s_=" << endl << MatrixXd(cup_1s_.template plain<double>().data) << endl;
210// cout << "cdn_1s_=" << endl << MatrixXd(cdn_1s_.template plain<double>().data) << endl;
211// cout << "cdagup_1s_=" << endl << MatrixXd(cdagup_1s_.template plain<double>().data) << endl;
212// cout << "cdagdn_1s_=" << endl << MatrixXd(cdagdn_1s_.template plain<double>().data) << endl;
213
214 return;
215}
216
217template<typename Symmetry_>
219fill_basis (bool REMOVE_DOUBLE, bool REMOVE_EMPTY, bool REMOVE_UP, bool REMOVE_DN)
220{
221 if constexpr (std::is_same<Symmetry, Sym::S1xS2<Sym::U1<Sym::SpinU1>,Sym::U1<Sym::ChargeU1> > >::value) //U1xU1
222 {
223 typename Symmetry::qType Q;
224 Eigen::Index inner_dim;
225 std::vector<std::string> ident;
226
227 if (!REMOVE_EMPTY)
228 {
229 Q={0,0}; //empty state
230 inner_dim = 1;
231 ident.push_back("empty");
232 basis_1s_.push_back(Q,inner_dim,ident);
233 ident.clear();
234 }
235
236 if (!REMOVE_UP)
237 {
238 Q={+mfactor,1}; //up spin state
239 inner_dim = 1;
240 ident.push_back("up");
241 basis_1s_.push_back(Q,inner_dim,ident);
242 ident.clear();
243 }
244
245 if (!REMOVE_DN)
246 {
247 Q={-mfactor,1}; //down spin state
248 inner_dim = 1;
249 ident.push_back("dn");
250 basis_1s_.push_back(Q,inner_dim,ident);
251 ident.clear();
252 }
253
254 if (!REMOVE_DOUBLE)
255 {
256 Q={0,2}; //doubly occupied state
257 inner_dim = 1;
258 ident.push_back("double");
259 basis_1s_.push_back(Q,inner_dim,ident);
260 ident.clear();
261 }
262 }
263 else if constexpr (std::is_same<Symmetry, Sym::U0>::value) //U0
264 {
265 typename Symmetry::qType Q = {}; //empty and doubly occupied state
266 Eigen::Index inner_dim;
267 std::vector<std::string> ident;
268
269 // all present
270 if (!REMOVE_DOUBLE and !REMOVE_EMPTY and !REMOVE_UP and !REMOVE_DN)
271 {
272 ident.push_back("empty");
273 ident.push_back("up");
274 ident.push_back("dn");
275 ident.push_back("double");
276 inner_dim = 4;
277 basis_1s_.push_back(Q,inner_dim,ident);
278 ident.clear();
279 }
280 // one removed
281 else if (REMOVE_DOUBLE and !REMOVE_EMPTY and !REMOVE_UP and !REMOVE_DN)
282 {
283 ident.push_back("empty");
284 ident.push_back("up");
285 ident.push_back("dn");
286 inner_dim = 3;
287 basis_1s_.push_back(Q,inner_dim,ident);
288 ident.clear();
289 }
290 else if (!REMOVE_DOUBLE and REMOVE_EMPTY and !REMOVE_UP and !REMOVE_DN)
291 {
292 ident.push_back("up");
293 ident.push_back("dn");
294 ident.push_back("double");
295 inner_dim = 3;
296 basis_1s_.push_back(Q,inner_dim,ident);
297 ident.clear();
298 }
299 else if (!REMOVE_DOUBLE and !REMOVE_EMPTY and REMOVE_UP and !REMOVE_DN)
300 {
301 ident.push_back("empty");
302 ident.push_back("dn");
303 ident.push_back("double");
304 inner_dim = 3;
305 basis_1s_.push_back(Q,inner_dim,ident);
306 ident.clear();
307 }
308 else if (!REMOVE_DOUBLE and !REMOVE_EMPTY and !REMOVE_UP and REMOVE_DN)
309 {
310 ident.push_back("empty");
311 ident.push_back("up");
312 ident.push_back("double");
313 inner_dim = 3;
314 basis_1s_.push_back(Q,inner_dim,ident);
315 ident.clear();
316 }
317 // two removed
318 else if (REMOVE_DOUBLE and REMOVE_EMPTY and !REMOVE_UP and !REMOVE_DN)
319 {
320 ident.push_back("up");
321 ident.push_back("dn");
322 inner_dim = 2;
323 basis_1s_.push_back(Q,inner_dim,ident);
324 ident.clear();
325 }
326 else if (!REMOVE_DOUBLE and !REMOVE_EMPTY and REMOVE_UP and REMOVE_DN)
327 {
328 ident.push_back("empty");
329 ident.push_back("double");
330 inner_dim = 2;
331 basis_1s_.push_back(Q,inner_dim,ident);
332 ident.clear();
333 }
334 else if (!REMOVE_DOUBLE and REMOVE_EMPTY and !REMOVE_UP and REMOVE_DN)
335 {
336 ident.push_back("double");
337 ident.push_back("up");
338 inner_dim = 2;
339 basis_1s_.push_back(Q,inner_dim,ident);
340 ident.clear();
341 }
342 else if (!REMOVE_DOUBLE and REMOVE_EMPTY and REMOVE_UP and !REMOVE_DN)
343 {
344 ident.push_back("double");
345 ident.push_back("dn");
346 inner_dim = 2;
347 basis_1s_.push_back(Q,inner_dim,ident);
348 ident.clear();
349 }
350 else if (REMOVE_DOUBLE and !REMOVE_EMPTY and !REMOVE_UP and REMOVE_DN)
351 {
352 ident.push_back("empty");
353 ident.push_back("up");
354 inner_dim = 2;
355 basis_1s_.push_back(Q,inner_dim,ident);
356 ident.clear();
357 }
358 else if (REMOVE_DOUBLE and !REMOVE_EMPTY and REMOVE_UP and !REMOVE_DN)
359 {
360 ident.push_back("empty");
361 ident.push_back("dn");
362 inner_dim = 2;
363 basis_1s_.push_back(Q,inner_dim,ident);
364 ident.clear();
365 }
366 // three removed
367 else
368 {
369 assert(1!=1 and "Trivial basis in FermionSite!");
370 }
371 }
372 else if constexpr (std::is_same<Symmetry, Sym::U1<Sym::SpinU1> >::value) //spin U1
373 {
374 typename Symmetry::qType Q; //empty and doubly occupied state
375 Eigen::Index inner_dim;
376 std::vector<std::string> ident;
377
378 if (!REMOVE_DOUBLE and !REMOVE_EMPTY)
379 {
380 Q={0}; //doubly occupied state
381 inner_dim = 2;
382 ident.push_back("empty");
383 ident.push_back("double");
384 basis_1s_.push_back(Q,inner_dim,ident);
385 ident.clear();
386 }
387 else if (!REMOVE_EMPTY and REMOVE_DOUBLE)
388 {
389 Q={0};
390 inner_dim = 1;
391 ident.push_back("empty");
392 basis_1s_.push_back(Q,inner_dim,ident);
393 ident.clear();
394 }
395 else if (REMOVE_EMPTY and !REMOVE_DOUBLE)
396 {
397 Q={0};
398 inner_dim = 1;
399 ident.push_back("double");
400 basis_1s_.push_back(Q,inner_dim,ident);
401 ident.clear();
402 }
403
404 if (!REMOVE_UP)
405 {
406 Q={+mfactor}; //up spin state
407 inner_dim = 1;
408 ident.push_back("up");
409 basis_1s_.push_back(Q,inner_dim,ident);
410 ident.clear();
411 }
412 if (!REMOVE_DN)
413 {
414 Q={-mfactor}; //down spin state
415 inner_dim = 1;
416 ident.push_back("dn");
417 basis_1s_.push_back(Q,inner_dim,ident);
418 ident.clear();
419 }
420 }
421 else if constexpr (std::is_same<Symmetry, Sym::U1<Sym::ChargeU1> >::value) //charge U1
422 {
423 typename Symmetry::qType Q;
424 Eigen::Index inner_dim;
425 std::vector<std::string> ident;
426
427 if (!REMOVE_EMPTY)
428 {
429 Q={0}; //empty and doubly occupied state
430 ident.push_back("empty");
431 inner_dim = 1;
432 basis_1s_.push_back(Q,inner_dim,ident);
433 ident.clear();
434 }
435
436 if (!REMOVE_UP and !REMOVE_DN)
437 {
438 Q={1}; //singly occupied states
439 inner_dim = 2;
440 ident.push_back("up");
441 ident.push_back("dn");
442 basis_1s_.push_back(Q,inner_dim,ident);
443 ident.clear();
444 }
445 else if (REMOVE_UP and !REMOVE_DN)
446 {
447 Q={1};
448 inner_dim = 1;
449 ident.push_back("dn");
450 basis_1s_.push_back(Q,inner_dim,ident);
451 ident.clear();
452 }
453 else if (!REMOVE_UP and REMOVE_DN)
454 {
455 Q={1};
456 inner_dim = 1;
457 ident.push_back("up");
458 basis_1s_.push_back(Q,inner_dim,ident);
459 ident.clear();
460 }
461
462 if (!REMOVE_DOUBLE)
463 {
464 Q={2}; //doubly occupied state
465 inner_dim = 1;
466 ident.push_back("double");
467 basis_1s_.push_back(Q,inner_dim,ident);
468 ident.clear();
469 }
470 }
471 else if constexpr (std::is_same<Symmetry, Sym::ZN<Sym::ChargeZ2,2> >::value) // charge Z2
472 {
473 typename Symmetry::qType Q; //empty and doubly occupied state
474 Eigen::Index inner_dim;
475 std::vector<std::string> ident;
476
477 if (!REMOVE_EMPTY and !REMOVE_DOUBLE)
478 {
479 Q={0}; //doubly occupied state
480 inner_dim = 2;
481 ident.push_back("empty");
482 ident.push_back("double");
483 basis_1s_.push_back(Q,inner_dim,ident);
484 ident.clear();
485 }
486 else if (!REMOVE_EMPTY and REMOVE_DOUBLE)
487 {
488 Q={0}; //doubly occupied state
489 inner_dim = 1;
490 ident.push_back("empty");
491 basis_1s_.push_back(Q,inner_dim,ident);
492 ident.clear();
493 }
494 else if (REMOVE_EMPTY and !REMOVE_DOUBLE)
495 {
496 Q={0}; //doubly occupied state
497 inner_dim = 1;
498 ident.push_back("double");
499 basis_1s_.push_back(Q,inner_dim,ident);
500 ident.clear();
501 }
502
503 if (!REMOVE_UP and !REMOVE_DN)
504 {
505 Q={1}; //doubly occupied state
506 inner_dim = 2;
507 ident.push_back("up");
508 ident.push_back("dn");
509 basis_1s_.push_back(Q,inner_dim,ident);
510 ident.clear();
511 }
512 else if (!REMOVE_UP and REMOVE_DN)
513 {
514 Q={1}; //doubly occupied state
515 inner_dim = 1;
516 ident.push_back("up");
517 basis_1s_.push_back(Q,inner_dim,ident);
518 ident.clear();
519 }
520 else if (REMOVE_UP and !REMOVE_DN)
521 {
522 Q={1}; //doubly occupied state
523 inner_dim = 1;
524 ident.push_back("dn");
525 basis_1s_.push_back(Q,inner_dim,ident);
526 ident.clear();
527 }
528 }
529 else if constexpr (Symmetry::kind()[0] == Sym::KIND::N and Symmetry::kind()[1] == Sym::KIND::K)
530 {
531 typename Symmetry::qType Q;
532 Eigen::Index inner_dim;
533 std::vector<std::string> ident;
534 int ZN = Symmetry::mod()[1];
535
536 if (!REMOVE_EMPTY)
537 {
538 Q={0,0};
539 inner_dim = 1;
540 ident.push_back("empty");
541 basis_1s_.push_back(Q,inner_dim,ident);
542 ident.clear();
543 }
544
545 if (!REMOVE_UP and !REMOVE_DN)
546 {
547 Q={1,posmod(k,ZN)};
548 inner_dim = 2;
549 ident.push_back("up");
550 ident.push_back("dn");
551 basis_1s_.push_back(Q,inner_dim,ident);
552 ident.clear();
553 }
554 else if (REMOVE_UP and !REMOVE_DN)
555 {
556 Q={1,posmod(k,ZN)};
557 inner_dim = 1;
558 ident.push_back("dn");
559 basis_1s_.push_back(Q,inner_dim,ident);
560 ident.clear();
561 }
562 else if (!REMOVE_UP and REMOVE_DN)
563 {
564 Q={1,posmod(k,ZN)};
565 inner_dim = 1;
566 ident.push_back("up");
567 basis_1s_.push_back(Q,inner_dim,ident);
568 ident.clear();
569 }
570
571 if (!REMOVE_DOUBLE)
572 {
573 Q={2,posmod(k+k,ZN)};
574 inner_dim = 1;
575 ident.push_back("double");
576 basis_1s_.push_back(Q,inner_dim,ident);
577 ident.clear();
578 }
579 }
580}
581
582template<typename Symmetry_>
583typename Symmetry_::qType FermionSite<Symmetry_>::
584getQ (SPIN_INDEX sigma, int Delta) const
585{
586 if constexpr (Symmetry::IS_TRIVIAL) {return {};}
587 else if constexpr (Symmetry::Nq == 1)
588 {
589 if constexpr (Symmetry::kind()[0] == Sym::KIND::N) //return particle number as good quantum number.
590 {
591 typename Symmetry::qType out;
592 if (sigma==UP) {out = {Delta};}
593 else if (sigma==DN) {out = {Delta};}
594 else if (sigma==UPDN) {out = {2*Delta};}
595 else if (sigma==NOSPIN) {out = Symmetry::qvacuum();}
596 return out;
597 }
598 else if constexpr (Symmetry::kind()[0] == Sym::KIND::M) //return magnetization as good quantum number.
599 {
600 typename Symmetry::qType out;
601 if (sigma==UP) {out = {mfactor*Delta};}
602 else if (sigma==DN) {out = {-mfactor*Delta};}
603 else if (sigma==UPDN) {out = Symmetry::qvacuum();}
604 else if (sigma==NOSPIN) {out = Symmetry::qvacuum();}
605 return out;
606 }
607 else if constexpr (Symmetry::kind()[0] == Sym::KIND::Nparity) //return parity as good quantum number (Delta even or odd).
608 {
609 typename Symmetry::qType out;
610 if (sigma==UP) {out = {posmod<2>(abs(Delta))};} // remove one particles = odd
611 else if (sigma==DN) {out = {posmod<2>(abs(Delta))};} // remove one particles = odd
612 else if (sigma==UPDN) {out = Symmetry::qvacuum();} // remove two particles = even = vacuum
613 else if (sigma==NOSPIN) {out = Symmetry::qvacuum();} // remove no particles = even = vacuum
614 return out;
615 }
616 else {assert(false and "Ill-defined KIND of the used Symmetry.");}
617 }
618 else if constexpr (Symmetry::Nq == 2)
619 {
620 typename Symmetry::qType out;
621 if constexpr (Symmetry::kind()[0] == Sym::KIND::N and Symmetry::kind()[1] == Sym::KIND::M)
622 {
623 if (sigma==UP) {out = {Delta,mfactor*Delta};}
624 else if (sigma==DN) {out = {Delta,-mfactor*Delta};}
625 else if (sigma==UPDN) {out = {2*Delta,0};}
626 else if (sigma==NOSPIN) {out = Symmetry::qvacuum();}
627 }
628 else if constexpr (Symmetry::kind()[0] == Sym::KIND::N and Symmetry::kind()[1] == Sym::KIND::K)
629 {
630 int ZN = Symmetry::mod()[1];
631 // Delta=-1 annhilates momentum of k = creates ZN-k
632 // Delta=+1 creates momentum of k
633 int Deltak, Delta2k;
634 if (Delta == -1)
635 {
636 Deltak = posmod(ZN-k,ZN);
637 Delta2k = posmod(ZN-k+ZN-k,ZN);
638 }
639 else if (Delta == 1)
640 {
641 Deltak = posmod(k,ZN);
642 Delta2k = posmod(k+k,ZN);
643 }
644
645 if (sigma==UP) {out = {Delta,Deltak};}
646 else if (sigma==DN) {out = {Delta,Deltak};}
647 else if (sigma==UPDN) {out = {2*Delta,Delta2k};}
648 else if (sigma==NOSPIN) {out = Symmetry::qvacuum();}
649 }
650 else if constexpr (Symmetry::kind()[0] == Sym::KIND::M and Symmetry::kind()[1] == Sym::KIND::N)
651 {
652 if (sigma==UP) {out = {mfactor*Delta,Delta};}
653 else if (sigma==DN) {out = {-mfactor*Delta,Delta};}
654 else if (sigma==UPDN) {out = {0,2*Delta};}
655 else if (sigma==NOSPIN) {out = Symmetry::qvacuum();}
656 }
657 // Not possible to use mfactor with these?
658 else if constexpr (Symmetry::kind()[0] == Sym::KIND::Nup and Symmetry::kind()[1] == Sym::KIND::Ndn)
659 {
660 if (sigma==UP) {out = {Delta,0};}
661 else if (sigma==DN) {out = {0,Delta};}
662 else if (sigma==UPDN) {out = {Delta,Delta};}
663 else if (sigma==NOSPIN) {out = Symmetry::qvacuum();}
664 }
665 else if constexpr (Symmetry::kind()[0] == Sym::KIND::Ndn and Symmetry::kind()[1] == Sym::KIND::Nup)
666 {
667 if (sigma==UP) {out = {0,Delta};}
668 else if (sigma==DN) {out = {Delta,0};}
669 else if (sigma==UPDN) {out = {Delta,Delta};}
670 else if (sigma==NOSPIN) {out = Symmetry::qvacuum();}
671 }
672 return out;
673 }
674 static_assert("You inserted a Symmetry which can not be handled by FermionBase.");
675}
676
677template<typename Symmetry_>
678typename Symmetry_::qType FermionSite<Symmetry_>::
679getQ (SPINOP_LABEL Sa) const
680{
681 if constexpr (Symmetry::IS_TRIVIAL) {return {};}
682 else if constexpr (Symmetry::Nq == 1)
683 {
684 if constexpr (Symmetry::kind()[0] == Sym::KIND::N or // particle number
685 Symmetry::kind()[0] == Sym::KIND::Nparity) // particle number parity
686 {
687 return Symmetry::qvacuum(); // spin flips remove no particles = even = vacuum
688 }
689 else if constexpr (Symmetry::kind()[0] == Sym::KIND::M) // magnetization
690 {
691 assert(Sa != SX and Sa != iSY);
692
693 typename Symmetry::qType out;
694 if (Sa==SZ) {out = {0};}
695 else if (Sa==SP) {out = {+2};}
696 else if (Sa==SM) {out = {-2};}
697 return out;
698 }
699 else {assert(false and "Ill defined KIND of the used Symmetry.");}
700 }
701 else if constexpr (Symmetry::Nq == 2)
702 {
703 assert(Sa != SX and Sa != iSY);
704
705 typename Symmetry::qType out;
706 if constexpr (Symmetry::kind()[0] == Sym::KIND::N and Symmetry::kind()[1] == Sym::KIND::M)
707 {
708 if (Sa==SZ) {out = {0,0};}
709 else if (Sa==SP) {out = {0,+2};}
710 else if (Sa==SM) {out = {0,-2};}
711 }
712 if constexpr (Symmetry::kind()[0] == Sym::KIND::N and Symmetry::kind()[1] == Sym::KIND::K)
713 {
714 // spinflip == no change of momentum
715 if (Sa==SZ) {out = {0,0};}
716 else if (Sa==SP) {out = {0,0};}
717 else if (Sa==SM) {out = {0,0};}
718 }
719 else if constexpr (Symmetry::kind()[0] == Sym::KIND::M and Symmetry::kind()[1] == Sym::KIND::N)
720 {
721 if (Sa==SZ) {out = {0,0};}
722 else if (Sa==SP) {out = {+2,0};}
723 else if (Sa==SM) {out = {-2,0};}
724 }
725 else if constexpr (Symmetry::kind()[0] == Sym::KIND::Nup and Symmetry::kind()[1] == Sym::KIND::Ndn)
726 {
727 if (Sa==SZ) {out = {0,0};}
728 else if (Sa==SP) {out = {+1,-1};}
729 else if (Sa==SM) {out = {-1,+1};}
730 }
731 else if constexpr (Symmetry::kind()[0] == Sym::KIND::Ndn and Symmetry::kind()[1] == Sym::KIND::Nup)
732 {
733 if (Sa==SZ) {out = {0,0};}
734 else if (Sa==SP) {out = {-1,+1};}
735 else if (Sa==SM) {out = {+1,-1};}
736 }
737 return out;
738 }
739 static_assert("You've inserted a symmetry which can not be handled by FermionSite.");
740}
741
742#endif //FERMIONSITE_H_
int posmod(int x)
Definition: DmrgExternal.h:20
SPIN_INDEX
Definition: DmrgTypedefs.h:36
@ DN
Definition: DmrgTypedefs.h:38
@ NOSPIN
Definition: DmrgTypedefs.h:39
@ UP
Definition: DmrgTypedefs.h:37
@ UPDN
Definition: DmrgTypedefs.h:40
SPINOP_LABEL
Definition: DmrgTypedefs.h:60
@ iSY
Definition: DmrgTypedefs.h:60
@ SZ
Definition: DmrgTypedefs.h:60
@ SP
Definition: DmrgTypedefs.h:60
@ SX
Definition: DmrgTypedefs.h:60
@ SM
Definition: DmrgTypedefs.h:60
void fill_SiteOps(bool REMOVE_DOUBLE, bool REMOVE_EMPTY, bool REMOVE_UP, bool REMOVE_DN)
Definition: FermionSite.h:102
OperatorType Sz_1s() const
Definition: FermionSite.h:39
OperatorType Tz_1s() const
Definition: FermionSite.h:44
OperatorType n_1s() const
Definition: FermionSite.h:33
void fill_basis(bool REMOVE_DOUBLE, bool REMOVE_EMPTY, bool REMOVE_UP, bool REMOVE_DN)
Definition: FermionSite.h:219
OperatorType Sp_1s_
Definition: FermionSite.h:78
OperatorType cdag_1s(SPIN_INDEX sigma) const
Definition: FermionSite.h:31
OperatorType Id_1s_
Definition: FermionSite.h:63
double Scalar
Definition: FermionSite.h:17
OperatorType F_1s_
Definition: FermionSite.h:64
OperatorType nh_1s() const
Definition: FermionSite.h:36
OperatorType n_1s_
Definition: FermionSite.h:72
ComplexOperatorType exp_ipiSz_1s_
Definition: FermionSite.h:80
ComplexOperatorType exp_ipiSz_1s() const
Definition: FermionSite.h:42
OperatorType cdagcdag_1s() const
Definition: FermionSite.h:46
Symmetry_ Symmetry
Definition: FermionSite.h:18
OperatorType cc_1s() const
Definition: FermionSite.h:45
OperatorType cdn_1s_
Definition: FermionSite.h:67
OperatorType Tz_1s_
Definition: FermionSite.h:82
OperatorType Sm_1s_
Definition: FermionSite.h:79
OperatorType n_1s(SPIN_INDEX sigma) const
Definition: FermionSite.h:34
OperatorType ndn_1s_
Definition: FermionSite.h:74
OperatorType cup_1s_
Definition: FermionSite.h:66
OperatorType cc_1s_
Definition: FermionSite.h:83
OperatorType cdagdn_1s_
Definition: FermionSite.h:70
OperatorType d_1s_
Definition: FermionSite.h:75
OperatorType cdagcdag_1s_
Definition: FermionSite.h:84
Qbasis< Symmetry > basis_1s_
Definition: FermionSite.h:61
Symmetry_::qType getQ(SPIN_INDEX sigma, int Delta) const
Definition: FermionSite.h:584
OperatorType c_1s(SPIN_INDEX sigma) const
Definition: FermionSite.h:30
OperatorType Sp_1s() const
Definition: FermionSite.h:40
OperatorType F_1s() const
Definition: FermionSite.h:28
OperatorType cdagup_1s_
Definition: FermionSite.h:69
Qbasis< Symmetry > basis_1s() const
Definition: FermionSite.h:48
SiteOperatorQ< Symmetry, Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > > OperatorType
Definition: FermionSite.h:19
OperatorType ns_1s() const
Definition: FermionSite.h:35
OperatorType nup_1s_
Definition: FermionSite.h:73
OperatorType Sm_1s() const
Definition: FermionSite.h:41
SiteOperatorQ< Symmetry, Eigen::Matrix< complex< Scalar >, Eigen::Dynamic, Eigen::Dynamic > > ComplexOperatorType
Definition: FermionSite.h:20
OperatorType d_1s() const
Definition: FermionSite.h:37
OperatorType Id_1s() const
Definition: FermionSite.h:27
OperatorType Sz_1s_
Definition: FermionSite.h:77
Definition: Qbasis.h:39
Definition: U1.h:25