1#ifndef STRAWBERRY_KONDOMODEL
2#define STRAWBERRY_KONDOMODEL
36class KondoU1xU1 :
public Mpo<Sym::S1xS2<Sym::U1<Sym::SpinU1>,Sym::U1<Sym::ChargeU1> >,double>,
37 public KondoObservables<Sym::S1xS2<Sym::U1<Sym::SpinU1>,Sym::U1<Sym::ChargeU1> > >,
68 template<
typename Symmetry_>
82 {
"t",1.}, {
"tPrime",0.}, {
"tRung",0.},
83 {
"Jxy",0.}, {
"Jz",0.}, {
"J",1.}, {
"Jdir",0.},
84 {
"U",0.}, {
"Uph",0.}, {
"V",0.}, {
"Vrung",0.},
86 {
"Bz",0.}, {
"Bzsub",0.}, {
"Kz",0.},
87 {
"Inext",0.}, {
"Iprev",0.}, {
"I3next",0.}, {
"I3prev",0.}, {
"I3loc",0.},
88 {
"D",2ul}, {
"maxPower",2ul}, {
"CYLINDER",
false}, {
"Ly",1ul}, {
"LyF",1ul}
93 {
"max_alpha",100.}, {
"min_alpha",1.}, {
"lim_alpha",11ul}, {
"eps_svd",1e-7},
94 {
"Dincr_abs",5ul}, {
"Dincr_per",2ul}, {
"Dincr_rel",1.1},
95 {
"min_Nsv",0ul}, {
"max_Nrich",-1},
96 {
"max_halfsweeps",20ul}, {
"min_halfsweeps",6ul},
97 {
"Dinit",5ul}, {
"Qinit",18ul}, {
"Dlimit",100ul},
98 {
"tol_eigval",1e-7}, {
"tol_state",1e-6},
108 ParamHandler P(params,defaults);
109 size_t Lcell = P.size();
111 for (
size_t l=0; l<N_sites; ++l)
113 N_phys += P.get<
size_t>(
"LyF",l%Lcell);
114 setLocBasis((
B[l].get_basis().combine(F[l].get_basis())).qloc(),l);
117 this->set_name(
"Kondo");
120 std::vector<std::vector<std::string>> labellist;
121 set_operators(
B, F, P, pushlist, labellist, boundary);
123 this->construct_from_pushlist(pushlist, labellist, Lcell);
126 this->precalc_TwoSiteData();
132 frac S_elec(qnum[1],2);
135 for (
size_t l=0; l<
N_sites; ++l)
137 Smax +=
static_cast<int>(
B[l].orbitals()) *
frac(
B[l].get_D()-1,2);
140 frac S_tot(qnum[0],2);
141 if (Smax.denominator() == S_tot.denominator() and S_tot<=Smax and qnum[1]<=2*
static_cast<int>(this->N_phys) and qnum[1]>0) {
return true;}
145template<
typename Symmetry_>
150 std::size_t Lcell = P.size();
154 for (std::size_t loc=0; loc<
N_sites; ++loc)
156 size_t lm1 = (loc==0)?
N_sites-1 : loc-1;
160 std::size_t Fprev_orbitals =
F[lm1].orbitals();
161 std::size_t Forbitals =
F[loc].orbitals();
162 std::size_t Fnext_orbitals =
F[lp1].orbitals();
163 std::size_t Fnextn_orbitals =
F[lp2].orbitals();
165 std::size_t Bprev_orbitals =
B[lm1].orbitals();
166 std::size_t Borbitals =
B[loc].orbitals();
167 std::size_t Bnext_orbitals =
B[lp1].orbitals();
168 std::size_t Bnextn_orbitals =
B[lp2].orbitals();
170 stringstream Slabel, LyLabel, LyFlabel;
172 LyLabel <<
"Ly=" << P.get<
size_t>(
"Ly",loc%Lcell);
173 LyFlabel <<
"LyF=" << P.get<
size_t>(
"LyF",loc%Lcell);
174 labellist[loc].push_back(Slabel.str());
175 labellist[loc].push_back(LyLabel.str());
176 labellist[loc].push_back(LyFlabel.str());
178 auto push_full = [&
N_sites, &loc, &
B, &
F, &P, &pushlist, &labellist, &boundary] (
string xxxFull,
string label,
179 const vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > &first,
180 const vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > &last,
181 vector<double> factor,
bool FERMIONIC) ->
void
183 ArrayXXd Full = P.get<Eigen::ArrayXXd>(xxxFull);
184 vector<vector<std::pair<size_t,double> > > R = Geometry2D::rangeFormat(Full);
186 if (
static_cast<bool>(boundary)) {assert(R.size() ==
N_sites and
"Use an (N_sites)x(N_sites) hopping matrix for open BC!");}
187 else {assert(R.size() >= 2*
N_sites and
"Use at least a (2*N_sites)x(N_sites) hopping matrix for infinite BC!");}
189 for (
size_t j=0; j<first.size(); j++)
190 for (
size_t h=0; h<R[loc].size(); ++h)
192 size_t range = R[loc][h].first;
193 double value = R[loc][h].second;
197 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > ops(range+1);
199 for (
size_t i=1; i<range; ++i)
204 ops[range] = last[j][(loc+range)%
N_sites];
205 pushlist.push_back(std::make_tuple(loc, ops, factor[j] * value));
210 ss <<
label <<
"(" << Geometry2D::hoppingInfo(Full) <<
")";
211 labellist[loc].push_back(ss.str());
225 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {cdagup_sign_local,cdagdn_sign_local,cup_sign_local,cdn_sign_local};
226 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {cup_ranges,cdn_ranges,cdagup_ranges,cdagdn_ranges};
227 push_full(
"tFull",
"tᵢⱼ", first, last, {-1.,-1.,1.,1.},
PROP::FERMIONIC);
230 if (P.HAS(
"JdirxyFull"))
233 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Sp_ranges(
N_sites);
234 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Sm_ranges(
N_sites);
237 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {Sm_ranges, Sp_ranges};
238 push_full(
"Jdirxyfull",
"Jdirxyᵢⱼ", first, last, {0.5,0.5},
PROP::BOSONIC);
241 if (P.HAS(
"JdirzFull"))
243 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {
kroneckerProduct(
B[loc].
Sz(0),
F[loc].Id())};
244 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Sz_ranges(
N_sites);
247 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {Sz_ranges};
248 push_full(
"Jdirzfull",
"Jdirzᵢⱼ", first, last, {1.0},
PROP::BOSONIC);
253 param1d Jxy = P.fill_array1d<
double>(
"Jxy",
"Jorbxy", Forbitals, loc%Lcell);
254 labellist[loc].push_back(Jxy.label);
256 param1d Jz = P.fill_array1d<
double>(
"Jz",
"Jorbz", Forbitals, loc%Lcell);
257 labellist[loc].push_back(Jz.label);
259 param1d J = P.fill_array1d<
double>(
"J",
"Jorb", Forbitals, loc%Lcell);
260 labellist[loc].push_back(J.label);
263 param1d U = P.fill_array1d<
double>(
"U",
"Uorb", Forbitals, loc%Lcell);
264 labellist[loc].push_back(U.label);
267 param1d Uph = P.fill_array1d<
double>(
"Uph",
"Uphorb", Forbitals, loc%Lcell);
268 labellist[loc].push_back(Uph.label);
271 param2d tPerp = P.fill_array2d<
double>(
"tRung",
"t",
"tPerp", Forbitals, loc%Lcell, P.get<
bool>(
"CYLINDER"));
272 labellist[loc].push_back(tPerp.label);
275 param2d Vperp = P.fill_array2d<
double>(
"Vrung",
"V",
"Vperp", Forbitals, loc%Lcell, P.get<
bool>(
"CYLINDER"));
276 labellist[loc].push_back(Vperp.label);
279 param1d mu = P.fill_array1d<
double>(
"mu",
"muorb", Forbitals, loc%Lcell);
280 labellist[loc].push_back(mu.label);
283 param1d t0 = P.fill_array1d<
double>(
"t0",
"t0orb", Forbitals, loc%Lcell);
284 labellist[loc].push_back(t0.label);
287 param1d Kz = P.fill_array1d<
double>(
"Kz",
"Kzorb", Forbitals, loc%Lcell);
288 labellist[loc].push_back(Kz.label);
291 param1d Bzsub = P.fill_array1d<
double>(
"Bzsub",
"Bzsuborb", Forbitals, loc%Lcell);
292 labellist[loc].push_back(Bzsub.label);
295 param1d Bz = P.fill_array1d<
double>(
"Bz",
"Bzorb", Forbitals, loc%Lcell);
296 labellist[loc].push_back(Bz.label);
299 param1d I3loc = P.fill_array1d<
double>(
"I3loc",
"I3locOrb", Forbitals, loc%Lcell);
300 labellist[loc].push_back(I3loc.label);
302 ArrayXXd Jxyperp =
B[loc].ZeroHopping();
303 ArrayXXd Jzperp =
B[loc].ZeroHopping();
304 ArrayXd Bxorb =
B[loc].ZeroField();
305 ArrayXd muorb =
B[loc].ZeroField();
306 ArrayXd nuorb =
B[loc].ZeroField();
307 ArrayXd Bxsuborb =
F[loc].ZeroField();
308 ArrayXd Kxorb =
B[loc].ZeroField();
309 ArrayXXd Dyperp =
B[loc].ZeroHopping();
310 ArrayXXd Jperp =
F[loc].ZeroHopping();
311 ArrayXXd Vxysubperp =
F[loc].ZeroHopping();
312 ArrayXXd Vzsubperp =
F[loc].ZeroHopping();
313 ArrayXXd C =
F[loc].ZeroHopping();
315 if (Borbitals > 0 and Forbitals > 0)
317 auto Himp =
kroneckerProduct(
B[loc].HeisenbergHamiltonian(Jxyperp,Jzperp,Bz.a,muorb,nuorb,Kz.a),
F[loc].Id());
318 auto Hsub =
kroneckerProduct(
B[loc].Id(),
F[loc].
template HubbardHamiltonian<double>(U.a,Uph.a,t0.a-mu.a,Bzsub.a,tPerp.a,Vperp.a,Vzsubperp,Vxysubperp,Jperp,Jperp,C));
319 auto Hloc = Himp + Hsub;
321 for (
int alfa=0; alfa<Forbitals; ++alfa)
324 if (abs(Jxy(alfa)) > 0. or abs(J(alfa)) > 0.)
326 assert(Forbitals == Borbitals and
"Can only do a Kondo ladder with the same amount of spins and fermionic orbitals in y-direction!");
330 if (abs(Jz(alfa)) > 0. or abs(J(alfa)))
332 assert(Forbitals == Borbitals and
"Can only do a Kondo ladder with the same amount of spins and fermionic orbitals in y-direction!");
337 for (
int alfa=0; alfa<Forbitals; ++alfa)
339 if (I3loc(alfa) != 0.)
341 assert(Forbitals == Borbitals and
"Can only do a Kondo ladder with the same amount of spins and fermionic orbitals in y-direction!");
352 param2d tPara = P.fill_array2d<
double>(
"t",
"tPara", {Forbitals, Fnext_orbitals}, loc%Lcell);
353 labellist[loc].push_back(tPara.label);
356 param2d Vpara = P.fill_array2d<
double>(
"V",
"Vpara", {Forbitals, Fnext_orbitals}, loc%Lcell);
357 labellist[loc].push_back(Vpara.label);
360 param2d JdirPara = P.fill_array2d<
double>(
"Jdir",
"JdirPara", {Borbitals, Bnext_orbitals}, loc%Lcell);
361 labellist[loc].push_back(JdirPara.label);
363 if (loc <
N_sites-1 or !
static_cast<bool>(boundary))
365 for (std::size_t alfa=0; alfa<Forbitals; ++alfa)
366 for (std::size_t beta=0; beta<Fnext_orbitals; ++beta)
385 for (
int alfa=0; alfa<Borbitals; ++alfa)
386 for (
int beta=0; beta<Bnext_orbitals; ++beta)
390 0.5*JdirPara(alfa,beta)));
393 0.5*JdirPara(alfa,beta)));
396 JdirPara(alfa,beta)));
402 param2d InextPara = P.fill_array2d<
double>(
"Inext",
"InextPara", {Borbitals, Fnext_orbitals}, loc%Lcell);
403 labellist[loc].push_back(InextPara.label);
405 if (loc <
N_sites-1 or !
static_cast<bool>(boundary))
407 for (std::size_t alfa=0; alfa<Borbitals; ++alfa)
408 for (std::size_t beta=0; beta<Fnext_orbitals; ++beta)
412 0.5*InextPara(alfa,beta)));
415 0.5*InextPara(alfa,beta)));
418 InextPara(alfa,beta)));
422 param2d IprevPara = P.fill_array2d<
double>(
"Iprev",
"IprevPara", {Fprev_orbitals, Borbitals}, loc%Lcell);
423 labellist[loc].push_back(IprevPara.label);
425 if (lm1 <
N_sites-1 or !
static_cast<bool>(boundary))
427 for (std::size_t alfa=0; alfa<Fprev_orbitals; ++alfa)
428 for (std::size_t beta=0; beta<Borbitals; ++beta)
432 0.5*IprevPara(alfa,beta)));
435 0.5*IprevPara(alfa,beta)));
438 IprevPara(alfa,beta)));
444 param2d I3nextPara = P.fill_array2d<
double>(
"I3next",
"I3nextPara", {Forbitals, Fnext_orbitals}, loc%Lcell);
445 labellist[loc].push_back(I3nextPara.label);
447 if (loc <
N_sites-1 or !
static_cast<bool>(boundary))
449 for (std::size_t alfa=0; alfa<Forbitals; ++alfa)
450 for (std::size_t beta=0; beta<Fnext_orbitals; ++beta)
452 assert(Borbitals == 1);
455 0.5*I3nextPara(alfa,beta)));
458 0.5*I3nextPara(alfa,beta)));
461 0.5*I3nextPara(alfa,beta)));
464 0.5*I3nextPara(alfa,beta)));
467 I3nextPara(alfa,beta)));
471 param2d I3prevPara = P.fill_array2d<
double>(
"I3prev",
"I3prevPara", {Fprev_orbitals, Forbitals}, loc%Lcell);
472 labellist[loc].push_back(I3prevPara.label);
474 if (lm1 <
N_sites-1 or !
static_cast<bool>(boundary))
476 for (std::size_t alfa=0; alfa<Fprev_orbitals; ++alfa)
477 for (std::size_t beta=0; beta<Forbitals; ++beta)
479 assert(Borbitals == 1);
482 0.5*I3nextPara(alfa,beta)));
485 0.5*I3nextPara(alfa,beta)));
488 0.5*I3nextPara(alfa,beta)));
491 0.5*I3nextPara(alfa,beta)));
494 I3nextPara(alfa,beta)));
500 param2d tPrime = P.fill_array2d<
double>(
"tPrime",
"tPrime_array", {Forbitals, Fnextn_orbitals}, loc%Lcell);
501 labellist[loc].push_back(tPrime.label);
503 if (loc <
N_sites-2 or !
static_cast<bool>(boundary))
505 for (std::size_t alfa=0; alfa<Forbitals; ++alfa)
506 for (std::size_t beta=0; beta<Fnextn_orbitals; ++beta)
511 -tPrime(alfa,beta)));
515 -tPrime(alfa,beta)));
519 -tPrime(alfa,beta)));
523 -tPrime(alfa,beta)));
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::U1< Sym::ChargeU1 > > > >::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::U1< Sym::ChargeU1 > > > >::type c(size_t locx, size_t locy=0, double factor=1.) const
vector< SpinBase< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::U1< Sym::ChargeU1 > > > > B
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::U1< Sym::ChargeU1 > > > >::type Sz(size_t locx, size_t locy=0) const
vector< FermionBase< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::U1< Sym::ChargeU1 > > > > F
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::U1< Sym::ChargeU1 > > > >::type n(size_t locx, size_t locy=0) const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::U1< Sym::ChargeU1 > > > >::type Scomp(SPINOP_LABEL Sa, size_t locx, size_t locy=0, double factor=1.) const
DMRG::VERBOSITY::OPTION VERB
Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::U1< Sym::ChargeU1 > > Symmetry
static const map< string, any > defaults
static constexpr MODEL_FAMILY FAMILY
static void set_operators(const std::vector< SpinBase< Symmetry_ > > &B, const std::vector< FermionBase< Symmetry_ > > &F, const ParamHandler &P, PushType< SiteOperator< Symmetry_, double >, double > &pushlist, std::vector< std::vector< std::string > > &labellist, const BC boundary=BC::OPEN)
static qarray< 2 > polaron(int L, int N=0)
static const map< string, any > sweep_defaults
static qarray< 2 > singlet(int N)
bool validate(qType qnum) const
#define MAKE_TYPEDEFS(MODEL)