14template <
typename Symmetry_>
25 FermionSite (
bool REMOVE_DOUBLE,
bool REMOVE_EMPTY,
bool REMOVE_UP,
bool REMOVE_DN,
int mfactor_input=1,
int k_input=0);
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);
58 typename Symmetry_::qType
getQ (
SPIN_INDEX sigma,
int Delta)
const;
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)
93 fill_basis(REMOVE_DOUBLE, REMOVE_EMPTY, REMOVE_UP, REMOVE_DN);
96 fill_SiteOps(REMOVE_DOUBLE, REMOVE_EMPTY, REMOVE_UP, REMOVE_DN);
100template <
typename Symmetry_>
102fill_SiteOps (
bool REMOVE_DOUBLE,
bool REMOVE_EMPTY,
bool REMOVE_UP,
bool REMOVE_DN)
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.;
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.;
140 if (!REMOVE_EMPTY and !REMOVE_UP)
142 cup_1s_(
"empty",
"up") = 1.;
143 cdagup_1s_(
"up",
"empty") = 1.;
145 if (!REMOVE_EMPTY and !REMOVE_DN)
147 cup_1s_(
"dn",
"double") = 1.;
148 cdagup_1s_(
"double",
"dn") = 1.;
151 if (!REMOVE_EMPTY and !REMOVE_DN)
153 cdn_1s_(
"empty",
"dn") = 1.;
154 cdagdn_1s_(
"dn",
"empty") = 1.;
156 if (!REMOVE_DOUBLE and !REMOVE_UP)
158 cdn_1s_(
"up",
"double") = -1.;
159 cdagdn_1s_(
"double",
"up") = -1.;
167 nup_1s_(
"up",
"up") = 1.;
171 ndn_1s_(
"dn",
"dn") = 1.;
175 nup_1s_(
"double",
"double") = 1.;
176 ndn_1s_(
"double",
"double") = 1.;
179 n_1s_ = nup_1s_+ndn_1s_;
181 if (!REMOVE_DOUBLE) d_1s_(
"double",
"double") = 1.;
183 if (!REMOVE_EMPTY and !REMOVE_DOUBLE)
185 cc_1s_(
"empty",
"double") = +1.;
186 cdagcdag_1s_(
"double",
"empty") = +1.;
195 if (!REMOVE_UP and !REMOVE_DN)
197 Sz_1s_ = 0.5*(nup_1s_-ndn_1s_);
198 Sp_1s_ = cup_1s_.adjoint() * cdn_1s_;
199 Sm_1s_ = Sp_1s_.adjoint();
201 exp_ipiSz_1s_(
"up",
"up") = 1.i;
202 exp_ipiSz_1s_(
"dn",
"dn") = -1.i;
205 if (!REMOVE_EMPTY) exp_ipiSz_1s_(
"empty",
"empty") = 1.+0.i;
206 if (!REMOVE_DOUBLE) exp_ipiSz_1s_(
"double",
"double") = 1.+0.i;
217template<
typename Symmetry_>
219fill_basis (
bool REMOVE_DOUBLE,
bool REMOVE_EMPTY,
bool REMOVE_UP,
bool REMOVE_DN)
223 typename Symmetry::qType Q;
224 Eigen::Index inner_dim;
225 std::vector<std::string> ident;
231 ident.push_back(
"empty");
232 basis_1s_.push_back(Q,inner_dim,ident);
240 ident.push_back(
"up");
241 basis_1s_.push_back(Q,inner_dim,ident);
249 ident.push_back(
"dn");
250 basis_1s_.push_back(Q,inner_dim,ident);
258 ident.push_back(
"double");
259 basis_1s_.push_back(Q,inner_dim,ident);
263 else if constexpr (std::is_same<Symmetry, Sym::U0>::value)
265 typename Symmetry::qType Q = {};
266 Eigen::Index inner_dim;
267 std::vector<std::string> ident;
270 if (!REMOVE_DOUBLE and !REMOVE_EMPTY and !REMOVE_UP and !REMOVE_DN)
272 ident.push_back(
"empty");
273 ident.push_back(
"up");
274 ident.push_back(
"dn");
275 ident.push_back(
"double");
277 basis_1s_.push_back(Q,inner_dim,ident);
281 else if (REMOVE_DOUBLE and !REMOVE_EMPTY and !REMOVE_UP and !REMOVE_DN)
283 ident.push_back(
"empty");
284 ident.push_back(
"up");
285 ident.push_back(
"dn");
287 basis_1s_.push_back(Q,inner_dim,ident);
290 else if (!REMOVE_DOUBLE and REMOVE_EMPTY and !REMOVE_UP and !REMOVE_DN)
292 ident.push_back(
"up");
293 ident.push_back(
"dn");
294 ident.push_back(
"double");
296 basis_1s_.push_back(Q,inner_dim,ident);
299 else if (!REMOVE_DOUBLE and !REMOVE_EMPTY and REMOVE_UP and !REMOVE_DN)
301 ident.push_back(
"empty");
302 ident.push_back(
"dn");
303 ident.push_back(
"double");
305 basis_1s_.push_back(Q,inner_dim,ident);
308 else if (!REMOVE_DOUBLE and !REMOVE_EMPTY and !REMOVE_UP and REMOVE_DN)
310 ident.push_back(
"empty");
311 ident.push_back(
"up");
312 ident.push_back(
"double");
314 basis_1s_.push_back(Q,inner_dim,ident);
318 else if (REMOVE_DOUBLE and REMOVE_EMPTY and !REMOVE_UP and !REMOVE_DN)
320 ident.push_back(
"up");
321 ident.push_back(
"dn");
323 basis_1s_.push_back(Q,inner_dim,ident);
326 else if (!REMOVE_DOUBLE and !REMOVE_EMPTY and REMOVE_UP and REMOVE_DN)
328 ident.push_back(
"empty");
329 ident.push_back(
"double");
331 basis_1s_.push_back(Q,inner_dim,ident);
334 else if (!REMOVE_DOUBLE and REMOVE_EMPTY and !REMOVE_UP and REMOVE_DN)
336 ident.push_back(
"double");
337 ident.push_back(
"up");
339 basis_1s_.push_back(Q,inner_dim,ident);
342 else if (!REMOVE_DOUBLE and REMOVE_EMPTY and REMOVE_UP and !REMOVE_DN)
344 ident.push_back(
"double");
345 ident.push_back(
"dn");
347 basis_1s_.push_back(Q,inner_dim,ident);
350 else if (REMOVE_DOUBLE and !REMOVE_EMPTY and !REMOVE_UP and REMOVE_DN)
352 ident.push_back(
"empty");
353 ident.push_back(
"up");
355 basis_1s_.push_back(Q,inner_dim,ident);
358 else if (REMOVE_DOUBLE and !REMOVE_EMPTY and REMOVE_UP and !REMOVE_DN)
360 ident.push_back(
"empty");
361 ident.push_back(
"dn");
363 basis_1s_.push_back(Q,inner_dim,ident);
369 assert(1!=1 and
"Trivial basis in FermionSite!");
372 else if constexpr (std::is_same<Symmetry, Sym::U1<Sym::SpinU1> >::value)
374 typename Symmetry::qType Q;
375 Eigen::Index inner_dim;
376 std::vector<std::string> ident;
378 if (!REMOVE_DOUBLE and !REMOVE_EMPTY)
382 ident.push_back(
"empty");
383 ident.push_back(
"double");
384 basis_1s_.push_back(Q,inner_dim,ident);
387 else if (!REMOVE_EMPTY and REMOVE_DOUBLE)
391 ident.push_back(
"empty");
392 basis_1s_.push_back(Q,inner_dim,ident);
395 else if (REMOVE_EMPTY and !REMOVE_DOUBLE)
399 ident.push_back(
"double");
400 basis_1s_.push_back(Q,inner_dim,ident);
408 ident.push_back(
"up");
409 basis_1s_.push_back(Q,inner_dim,ident);
416 ident.push_back(
"dn");
417 basis_1s_.push_back(Q,inner_dim,ident);
421 else if constexpr (std::is_same<Symmetry, Sym::U1<Sym::ChargeU1> >::value)
423 typename Symmetry::qType Q;
424 Eigen::Index inner_dim;
425 std::vector<std::string> ident;
430 ident.push_back(
"empty");
432 basis_1s_.push_back(Q,inner_dim,ident);
436 if (!REMOVE_UP and !REMOVE_DN)
440 ident.push_back(
"up");
441 ident.push_back(
"dn");
442 basis_1s_.push_back(Q,inner_dim,ident);
445 else if (REMOVE_UP and !REMOVE_DN)
449 ident.push_back(
"dn");
450 basis_1s_.push_back(Q,inner_dim,ident);
453 else if (!REMOVE_UP and REMOVE_DN)
457 ident.push_back(
"up");
458 basis_1s_.push_back(Q,inner_dim,ident);
466 ident.push_back(
"double");
467 basis_1s_.push_back(Q,inner_dim,ident);
471 else if constexpr (std::is_same<Symmetry, Sym::ZN<Sym::ChargeZ2,2> >::value)
473 typename Symmetry::qType Q;
474 Eigen::Index inner_dim;
475 std::vector<std::string> ident;
477 if (!REMOVE_EMPTY and !REMOVE_DOUBLE)
481 ident.push_back(
"empty");
482 ident.push_back(
"double");
483 basis_1s_.push_back(Q,inner_dim,ident);
486 else if (!REMOVE_EMPTY and REMOVE_DOUBLE)
490 ident.push_back(
"empty");
491 basis_1s_.push_back(Q,inner_dim,ident);
494 else if (REMOVE_EMPTY and !REMOVE_DOUBLE)
498 ident.push_back(
"double");
499 basis_1s_.push_back(Q,inner_dim,ident);
503 if (!REMOVE_UP and !REMOVE_DN)
507 ident.push_back(
"up");
508 ident.push_back(
"dn");
509 basis_1s_.push_back(Q,inner_dim,ident);
512 else if (!REMOVE_UP and REMOVE_DN)
516 ident.push_back(
"up");
517 basis_1s_.push_back(Q,inner_dim,ident);
520 else if (REMOVE_UP and !REMOVE_DN)
524 ident.push_back(
"dn");
525 basis_1s_.push_back(Q,inner_dim,ident);
529 else if constexpr (Symmetry::kind()[0] == Sym::KIND::N and Symmetry::kind()[1] == Sym::KIND::K)
531 typename Symmetry::qType Q;
532 Eigen::Index inner_dim;
533 std::vector<std::string> ident;
534 int ZN = Symmetry::mod()[1];
540 ident.push_back(
"empty");
541 basis_1s_.push_back(Q,inner_dim,ident);
545 if (!REMOVE_UP and !REMOVE_DN)
549 ident.push_back(
"up");
550 ident.push_back(
"dn");
551 basis_1s_.push_back(Q,inner_dim,ident);
554 else if (REMOVE_UP and !REMOVE_DN)
558 ident.push_back(
"dn");
559 basis_1s_.push_back(Q,inner_dim,ident);
562 else if (!REMOVE_UP and REMOVE_DN)
566 ident.push_back(
"up");
567 basis_1s_.push_back(Q,inner_dim,ident);
575 ident.push_back(
"double");
576 basis_1s_.push_back(Q,inner_dim,ident);
582template<
typename Symmetry_>
586 if constexpr (Symmetry::IS_TRIVIAL) {
return {};}
587 else if constexpr (Symmetry::Nq == 1)
589 if constexpr (Symmetry::kind()[0] == Sym::KIND::N)
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();}
598 else if constexpr (Symmetry::kind()[0] == Sym::KIND::M)
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();}
607 else if constexpr (Symmetry::kind()[0] == Sym::KIND::Nparity)
609 typename Symmetry::qType out;
610 if (sigma==
UP) {out = {posmod<2>(abs(Delta))};}
611 else if (sigma==
DN) {out = {posmod<2>(abs(Delta))};}
612 else if (sigma==
UPDN) {out = Symmetry::qvacuum();}
613 else if (sigma==
NOSPIN) {out = Symmetry::qvacuum();}
616 else {assert(
false and
"Ill-defined KIND of the used Symmetry.");}
618 else if constexpr (Symmetry::Nq == 2)
620 typename Symmetry::qType out;
621 if constexpr (Symmetry::kind()[0] == Sym::KIND::N and Symmetry::kind()[1] == Sym::KIND::M)
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();}
628 else if constexpr (Symmetry::kind()[0] == Sym::KIND::N and Symmetry::kind()[1] == Sym::KIND::K)
630 int ZN = Symmetry::mod()[1];
637 Delta2k =
posmod(ZN-k+ZN-k,ZN);
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();}
650 else if constexpr (Symmetry::kind()[0] == Sym::KIND::M and Symmetry::kind()[1] == Sym::KIND::N)
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();}
658 else if constexpr (Symmetry::kind()[0] == Sym::KIND::Nup and Symmetry::kind()[1] == Sym::KIND::Ndn)
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();}
665 else if constexpr (Symmetry::kind()[0] == Sym::KIND::Ndn and Symmetry::kind()[1] == Sym::KIND::Nup)
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();}
674 static_assert(
"You inserted a Symmetry which can not be handled by FermionBase.");
677template<
typename Symmetry_>
681 if constexpr (Symmetry::IS_TRIVIAL) {
return {};}
682 else if constexpr (Symmetry::Nq == 1)
684 if constexpr (Symmetry::kind()[0] == Sym::KIND::N or
685 Symmetry::kind()[0] == Sym::KIND::Nparity)
687 return Symmetry::qvacuum();
689 else if constexpr (Symmetry::kind()[0] == Sym::KIND::M)
691 assert(Sa !=
SX and Sa !=
iSY);
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};}
699 else {assert(
false and
"Ill defined KIND of the used Symmetry.");}
701 else if constexpr (Symmetry::Nq == 2)
703 assert(Sa !=
SX and Sa !=
iSY);
705 typename Symmetry::qType out;
706 if constexpr (Symmetry::kind()[0] == Sym::KIND::N and Symmetry::kind()[1] == Sym::KIND::M)
708 if (Sa==
SZ) {out = {0,0};}
709 else if (Sa==
SP) {out = {0,+2};}
710 else if (Sa==
SM) {out = {0,-2};}
712 if constexpr (Symmetry::kind()[0] == Sym::KIND::N and Symmetry::kind()[1] == Sym::KIND::K)
715 if (Sa==
SZ) {out = {0,0};}
716 else if (Sa==
SP) {out = {0,0};}
717 else if (Sa==
SM) {out = {0,0};}
719 else if constexpr (Symmetry::kind()[0] == Sym::KIND::M and Symmetry::kind()[1] == Sym::KIND::N)
721 if (Sa==
SZ) {out = {0,0};}
722 else if (Sa==
SP) {out = {+2,0};}
723 else if (Sa==
SM) {out = {-2,0};}
725 else if constexpr (Symmetry::kind()[0] == Sym::KIND::Nup and Symmetry::kind()[1] == Sym::KIND::Ndn)
727 if (Sa==
SZ) {out = {0,0};}
728 else if (Sa==
SP) {out = {+1,-1};}
729 else if (Sa==
SM) {out = {-1,+1};}
731 else if constexpr (Symmetry::kind()[0] == Sym::KIND::Ndn and Symmetry::kind()[1] == Sym::KIND::Nup)
733 if (Sa==
SZ) {out = {0,0};}
734 else if (Sa==
SP) {out = {-1,+1};}
735 else if (Sa==
SM) {out = {+1,-1};}
739 static_assert(
"You've inserted a symmetry which can not be handled by FermionSite.");
void fill_SiteOps(bool REMOVE_DOUBLE, bool REMOVE_EMPTY, bool REMOVE_UP, bool REMOVE_DN)
OperatorType Sz_1s() const
OperatorType Tz_1s() const
OperatorType n_1s() const
void fill_basis(bool REMOVE_DOUBLE, bool REMOVE_EMPTY, bool REMOVE_UP, bool REMOVE_DN)
OperatorType cdag_1s(SPIN_INDEX sigma) const
OperatorType nh_1s() const
ComplexOperatorType exp_ipiSz_1s_
ComplexOperatorType exp_ipiSz_1s() const
OperatorType cdagcdag_1s() const
OperatorType cc_1s() const
OperatorType n_1s(SPIN_INDEX sigma) const
OperatorType cdagcdag_1s_
Qbasis< Symmetry > basis_1s_
Symmetry_::qType getQ(SPIN_INDEX sigma, int Delta) const
OperatorType c_1s(SPIN_INDEX sigma) const
OperatorType Sp_1s() const
OperatorType F_1s() const
Qbasis< Symmetry > basis_1s() const
SiteOperatorQ< Symmetry, Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > > OperatorType
OperatorType ns_1s() const
OperatorType Sm_1s() const
SiteOperatorQ< Symmetry, Eigen::Matrix< complex< Scalar >, Eigen::Dynamic, Eigen::Dynamic > > ComplexOperatorType
OperatorType d_1s() const
OperatorType Id_1s() const