1#ifndef KONDOMODEL_SU2XSU2_H_
2#define KONDOMODEL_SU2XSU2_H_
11#include "Geometry2D.h"
17class KondoU1xSU2 :
public Mpo<Sym::S1xS2<Sym::U1<Sym::SpinU1>,Sym::SU2<Sym::ChargeSU2> > ,double>,
18 public KondoObservables<Sym::S1xS2<Sym::U1<Sym::SpinU1>,Sym::SU2<Sym::ChargeSU2> > >,
24 typedef Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>
MatrixType;
42 int T = abs(0.5*(N-L));
46 template<
typename Symmetry_>
49 const BC boundary=BC::OPEN);
51 static const std::map<string,std::any>
defaults;
57 {
"t",1.}, {
"tRung",0.}, {
"tPrime",0.}, {
"tPrimePrime",0.},
58 {
"J",1.}, {
"Jz",0.}, {
"U",0.},
59 {
"V",0.}, {
"Vrung",0.},
60 {
"Bz",0.}, {
"Bzsub",0.}, {
"Kz",0.},
61 {
"Inext",0.}, {
"Iprev",0.}, {
"I3next",0.}, {
"I3prev",0.}, {
"I3loc",0.},
62 {
"D",2ul}, {
"maxPower",1ul}, {
"CYLINDER",
false}, {
"Ly",1ul}, {
"LyF",1ul},
63 {
"REMOVE_DOUBLE",
false}, {
"REMOVE_EMPTY",
false}, {
"REMOVE_UP",
false}, {
"REMOVE_DN",
false}, {
"mfactor",1}, {
"k",1},
68 {
"max_alpha",100.}, {
"min_alpha",1.}, {
"lim_alpha",16ul}, {
"eps_svd",1e-7},
69 {
"Dincr_abs",5ul}, {
"Dincr_per",2ul}, {
"Dincr_rel",1.1},
70 {
"min_Nsv",0ul}, {
"max_Nrich",-1},
71 {
"max_halfsweeps",30ul}, {
"min_halfsweeps",10ul},
72 {
"Dinit",5ul}, {
"Qinit",6ul}, {
"Dlimit",200ul},
73 {
"tol_eigval",1e-6}, {
"tol_state",1e-5},
83 ParamHandler P(params,defaults);
84 size_t Lcell = P.size();
86 for (
size_t l=0; l<N_sites; ++l)
88 N_phys += P.get<
size_t>(
"LyF",l%Lcell);
89 setLocBasis((
B[l].get_basis().combine(F[l].get_basis())).qloc(),l);
92 this->set_name(
"Kondo");
95 std::vector<std::vector<std::string>> labellist;
96 set_operators(
B, F, G, P, pushlist, labellist, boundary);
98 this->construct_from_pushlist(pushlist, labellist, Lcell);
101 this->precalc_TwoSiteData();
104template<
typename Symmetry_>
109 std::size_t Lcell = P.size();
113 for (std::size_t loc=0; loc<
N_sites; ++loc)
122 std::size_t Forbitals =
F[loc].orbitals();
123 std::size_t Fnext_orbitals =
F[lp1].orbitals();
124 std::size_t Fnextn_orbitals =
F[lp2].orbitals();
126 std::size_t Borbitals =
B[loc].orbitals();
127 std::size_t Bnext_orbitals =
B[lp1].orbitals();
128 std::size_t Bnextn_orbitals =
B[lp2].orbitals();
132 labellist[loc].push_back(Slabel.str());
134 auto push_full = [&
N_sites, &loc, &
B, &
F, &P, &pushlist, &labellist, &boundary] (
string xxxFull,
string label,
135 const vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > &first,
136 const vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > &last,
137 vector<double> factor,
bool FERMIONIC) ->
void
139 ArrayXXd Full = P.get<Eigen::ArrayXXd>(xxxFull);
140 vector<vector<std::pair<size_t,double> > > R = Geometry2D::rangeFormat(Full);
142 if (
static_cast<bool>(boundary)) {assert(R.size() ==
N_sites and
"Use an (N_sites)x(N_sites) hopping matrix for open BC!");}
143 else {assert(R.size() >= 2*
N_sites and
"Use at least a (2*N_sites)x(N_sites) hopping matrix for infinite BC!");}
145 for (
size_t j=0; j<first.size(); j++)
146 for (
size_t h=0; h<R[loc].size(); ++h)
148 size_t range = R[loc][h].first;
149 double value = R[loc][h].second;
153 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > ops(range+1);
155 for (
size_t i=1; i<range; ++i)
160 ops[range] = last[j][(loc+range)%
N_sites];
161 pushlist.push_back(std::make_tuple(loc, ops, factor[j] * value));
166 ss <<
label <<
"(" << Geometry2D::hoppingInfo(Full) <<
")";
167 labellist[loc].push_back(ss.str());
174 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > cUP_ranges(
N_sites);
175 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > cDN_ranges(
N_sites);
176 for (
size_t i=0; i<
N_sites; i++)
181 for (
size_t i=0; i<
N_sites; i++)
187 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {cdagUP_sign_local, cdagDN_sign_local};
188 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {cUP_ranges, cDN_ranges};
189 push_full(
"tFull",
"tᵢⱼ", first, last, {-std::sqrt(2.), -std::sqrt(2.)},
PROP::FERMIONIC);
194 param2d tPara = P.fill_array2d<
double>(
"t",
"tPara", {Forbitals, Fnext_orbitals}, loc%Lcell);
195 labellist[loc].push_back(tPara.label);
197 if (loc <
N_sites-1 or !
static_cast<bool>(boundary))
199 for (
int alfa=0; alfa<Forbitals; ++alfa)
200 for (
int beta=0; beta<Fnext_orbitals; ++beta)
208 auto Otmp_loc = PsiDagUp_loc * Sign_loc;
212 Otmp_loc = PsiDagDn_loc * Sign_loc;
221 param1d J = P.fill_array1d<
double>(
"J",
"Jorb", Forbitals, loc%Lcell);
222 labellist[loc].push_back(J.label);
225 param1d Jz = P.fill_array1d<
double>(
"Jz",
"Jzorb", Forbitals, loc%Lcell);
226 labellist[loc].push_back(Jz.label);
229 param2d tPerp = P.fill_array2d<
double>(
"tRung",
"t",
"tPerp", Forbitals, loc%Lcell, P.get<
bool>(
"CYLINDER"));
230 labellist[loc].push_back(tPerp.label);
233 param1d U = P.fill_array1d<
double>(
"U",
"Uorb", Forbitals, loc%Lcell);
234 labellist[loc].push_back(U.label);
237 param1d Bzsub = P.fill_array1d<
double>(
"Bzsub",
"Bzsuborb", Forbitals, loc%Lcell);
238 labellist[loc].push_back(Bzsub.label);
241 param1d Bz = P.fill_array1d<
double>(
"Bz",
"Bzorb", Borbitals, loc%Lcell);
242 labellist[loc].push_back(Bz.label);
245 param1d Kz = P.fill_array1d<
double>(
"Kz",
"Kzorb", Borbitals, loc%Lcell);
246 labellist[loc].push_back(Kz.label);
248 ArrayXXd muPerp =
B[loc].ZeroHopping();
249 ArrayXXd nuPerp =
B[loc].ZeroHopping();
250 ArrayXXd Jxyperp =
B[loc].ZeroHopping();
251 ArrayXXd Jzperp =
B[loc].ZeroHopping();
254 auto KondoHamiltonian =
kroneckerProduct(
B[loc].HeisenbergHamiltonian(Jxyperp,Jzperp,Bz.a,muPerp,nuPerp,Kz.a),
F[loc].Id());
256 ArrayXXd Vperp =
F[loc].ZeroHopping();
257 ArrayXXd Jxysubperp =
F[loc].ZeroHopping();
258 ArrayXXd Jzsubperp =
F[loc].ZeroHopping();
261 KondoHamiltonian +=
kroneckerProduct(
B[loc].Id(),
F[loc].HubbardHamiltonian(U.a,tPerp.a,Vperp,Jzsubperp,Jxysubperp,Bzsub.a));
264 for (
int alfa=0; alfa<Forbitals; ++alfa)
268 assert(Borbitals == Forbitals and
"Can only do a Kondo ladder with the same amount of spins and fermionic orbitals in y-direction!");
boost::rational< int > frac
std::string print_frac_nice(frac r)
SiteOperator< Symmetry, Scalar_ > kroneckerProduct(const SiteOperator< Symmetry, Scalar_ > &O1, const SiteOperator< Symmetry, Scalar_ > &O2)
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::SU2< Sym::ChargeSU2 > > > >::type cdag(size_t locx, size_t locy=0, double factor=std::sqrt(2.)) const
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::SU2< Sym::ChargeSU2 > > > >::type c(size_t locx, size_t locy=0, double factor=1.) const
vector< SpinBase< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::SU2< Sym::ChargeSU2 > > > > B
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::SU2< Sym::ChargeSU2 > > > >::type Sz(size_t locx, size_t locy=0) const
vector< FermionBase< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::SU2< Sym::ChargeSU2 > > > > F
std::enable_if< Dummy::IS_CHARGE_SU2(), Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::SU2< Sym::ChargeSU2 > > > >::type T(size_t locx, size_t locy=0, double factor=1.) const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::SU2< Sym::ChargeSU2 > > > >::type Scomp(SPINOP_LABEL Sa, size_t locx, size_t locy=0, double factor=1.) const
DMRG::VERBOSITY::OPTION VERB
static const std::map< string, std::any > defaults
static void set_operators(const std::vector< SpinBase< Symmetry_ > > &B, const std::vector< FermionBase< Symmetry_ > > &F, const vector< SUB_LATTICE > &G, const ParamHandler &P, PushType< SiteOperator< Symmetry_, double >, double > &pushlist, std::vector< std::vector< std::string > > &labellist, const BC boundary=BC::OPEN)
static qarray< 2 > singlet(int N=0, int L=0)
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixType
SiteOperatorQ< Symmetry, MatrixType > OperatorType
static constexpr MODEL_FAMILY FAMILY
static const map< string, any > sweep_defaults
Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::SU2< Sym::ChargeSU2 > > Symmetry
#define MAKE_TYPEDEFS(MODEL)