1#ifndef KONDOMODELSU2XU1_H_
2#define KONDOMODELSU2XU1_H_
15#include "Geometry2D.h"
37class KondoSU2xU1 :
public Mpo<Sym::S1xS2<Sym::SU2<Sym::SpinSU2>,Sym::U1<Sym::ChargeU1> >,double>,
38 public KondoObservables<Sym::S1xS2<Sym::SU2<Sym::SpinSU2>,Sym::U1<Sym::ChargeU1> > >,
49 typedef Eigen::Matrix<
double,Eigen::Dynamic,Eigen::Dynamic>
MatrixType;
71 template<
typename Symmetry_>
74 const BC boundary=BC::OPEN);
137 {
"t",1.}, {
"tPrime",0.}, {
"tRung",0.},
138 {
"J",1.}, {
"Jdir",0.},
139 {
"U",0.}, {
"Uph",0.},
140 {
"V",0.}, {
"Vrung",0.},
141 {
"mu",0.}, {
"t0",0.},
142 {
"Inext",0.}, {
"Iprev",0.}, {
"I3next",0.}, {
"I3prev",0.}, {
"I3loc",0.},
143 {
"D",2ul}, {
"maxPower",2ul}, {
"CYLINDER",
false}, {
"Ly",1ul}, {
"LyF",1ul}
148 {
"max_alpha",100.}, {
"min_alpha",1.}, {
"lim_alpha",11ul}, {
"eps_svd",1.e-7},
149 {
"Mincr_abs", 50ul}, {
"Mincr_per", 2ul}, {
"Mincr_rel", 1.1},
150 {
"min_Nsv",0ul}, {
"max_Nrich",-1},
151 {
"max_halfsweeps",30ul}, {
"min_halfsweeps",6ul},
152 {
"Minit",1ul}, {
"Qinit",1ul}, {
"Mlimit",10000ul},
153 {
"tol_eigval",1.e-7}, {
"tol_state",1.e-6},
165 size_t Lcell = P.size();
167 for (
size_t l=0; l<
N_sites; ++l)
169 N_phys += P.get<
size_t>(
"LyF",l%Lcell);
170 setLocBasis((
B[l].get_basis().combine(
F[l].get_basis())).qloc(),l);
176 std::vector<std::vector<std::string>> labellist;
188 frac S_elec(qnum[1],2);
190 for (
size_t l=0; l<
N_sites; ++l) { Smax+=
static_cast<int>(
B[l].orbitals())*
frac(
B[l].get_D()-1,2); }
192 frac S_tot(qnum[0]-1,2);
193 if (Smax.denominator()==S_tot.denominator() and S_tot<=Smax and qnum[0]<=2*2*
static_cast<int>(this->N_phys) and qnum[0]>0) {
return true;}
197template<
typename Symmetry_>
202 std::size_t Lcell = P.size();
206 for (std::size_t loc=0; loc<
N_sites; ++loc)
208 size_t lm1 = (loc==0)?
N_sites-1 : loc-1;
212 std::size_t Forbitals =
F[loc].orbitals();
213 std::size_t Fnext_orbitals =
F[(loc+1)%
N_sites].orbitals();
214 std::size_t Fnextn_orbitals =
F[(loc+2)%
N_sites].orbitals();
216 std::size_t Borbitals =
B[loc].orbitals();
217 std::size_t Bnext_orbitals =
B[(loc+1)%
N_sites].orbitals();
218 std::size_t Bnextn_orbitals =
B[(loc+2)%
N_sites].orbitals();
222 labellist[loc].push_back(Slabel.str());
224 auto push_full = [&
N_sites, &loc, &
B, &
F, &P, &pushlist, &labellist, &boundary] (
string xxxFull,
string label,
225 const vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > &first,
226 const vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > &last,
227 vector<double> factor,
bool FERMIONIC) ->
void
229 ArrayXXd Full = P.get<Eigen::ArrayXXd>(xxxFull);
230 vector<vector<std::pair<size_t,double> > > R = Geometry2D::rangeFormat(Full);
232 if (
static_cast<bool>(boundary)) {assert(R.size() ==
N_sites and
"Use an (N_sites)x(N_sites) hopping matrix for open BC!");}
233 else {assert(R.size() >= 2*
N_sites and
"Use at least a (2*N_sites)x(N_sites) hopping matrix for infinite BC!");}
235 for (
size_t j=0; j<first.size(); j++)
236 for (
size_t h=0; h<R[loc].size(); ++h)
238 size_t range = R[loc][h].first;
239 double value = R[loc][h].second;
243 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > ops(range+1);
245 for (
size_t i=1; i<range; ++i)
250 ops[range] = last[j][(loc+range)%
N_sites];
251 pushlist.push_back(std::make_tuple(loc, ops, factor[j] * value));
256 ss <<
label <<
"(" << Geometry2D::hoppingInfo(Full) <<
")";
257 labellist[loc].push_back(ss.str());
267 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {cdag_sign_local,c_sign_local};
268 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {c_ranges,cdag_ranges};
269 push_full(
"tFull",
"tᵢⱼ", first, last, {-std::sqrt(2.),-std::sqrt(2.)},
PROP::FERMIONIC);
272 if (P.HAS(
"JdirFull"))
274 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {
kroneckerProduct(
B[loc].Sdag(0),
F[loc].Id())};
275 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > S_ranges(
N_sites);
278 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {S_ranges};
279 push_full(
"Jdirfull",
"Jdirᵢⱼ", first, last, {std::sqrt(3.)},
PROP::BOSONIC);
285 param1d J = P.fill_array1d<
double>(
"J",
"Jorb", Forbitals, loc%Lcell);
286 labellist[loc].push_back(J.label);
289 param2d tPerp = P.fill_array2d<
double>(
"tRung",
"t",
"tPerp", Forbitals, loc%Lcell, P.get<
bool>(
"CYLINDER"));
290 labellist[loc].push_back(tPerp.label);
293 param2d Vperp = P.fill_array2d<
double>(
"Vrung",
"V",
"Vperp", Forbitals, loc%Lcell, P.get<
bool>(
"CYLINDER"));
294 labellist[loc].push_back(Vperp.label);
297 param1d U = P.fill_array1d<
double>(
"U",
"Uorb", Forbitals, loc%Lcell);
298 labellist[loc].push_back(U.label);
301 param1d Uph = P.fill_array1d<
double>(
"Uph",
"Uphorb", Forbitals, loc%Lcell);
302 labellist[loc].push_back(Uph.label);
305 param1d mu = P.fill_array1d<
double>(
"mu",
"muorb", Forbitals, loc%Lcell);
306 labellist[loc].push_back(mu.label);
309 param1d t0 = P.fill_array1d<
double>(
"t0",
"t0orb", Forbitals, loc%Lcell);
310 labellist[loc].push_back(t0.label);
312 if (
F[loc].
dim() > 1)
314 OperatorType KondoHamiltonian({1,0},
B[loc].get_basis().combine(
F[loc].get_basis()));
316 ArrayXXd Jperp =
B[loc].ZeroHopping();
317 ArrayXXd Jperpsub =
F[loc].ZeroHopping();
318 ArrayXXd Vz =
F[loc].ZeroHopping();
319 ArrayXXd Vxy =
F[loc].ZeroHopping();
322 KondoHamiltonian =
kroneckerProduct(
B[loc].Id(),
F[loc].
template HubbardHamiltonian<double>(U.a,Uph.a,t0.a-mu.a,tPerp.a,Vperp.a,Vz,Vxy,Jperpsub));
328 for (
int alfa=0; alfa<Forbitals; ++alfa)
330 assert(Borbitals == Forbitals and
"Can only do a Kondo ladder with the same amount of spins and fermionic orbitals in y-direction!");
341 param2d tPara = P.fill_array2d<
double>(
"t",
"tPara", {Forbitals, Fnext_orbitals}, loc%Lcell);
342 labellist[loc].push_back(tPara.label);
345 param2d Vpara = P.fill_array2d<
double>(
"V",
"Vpara", {Forbitals, Fnext_orbitals}, loc%Lcell);
346 labellist[loc].push_back(Vpara.label);
349 param2d JdirPara = P.fill_array2d<
double>(
"Jdir",
"JdirPara", {Borbitals, Bnext_orbitals}, loc%Lcell);
350 labellist[loc].push_back(JdirPara.label);
352 if (loc <
N_sites-1 or !
static_cast<bool>(boundary))
354 for (
int alfa=0; alfa<Forbitals; ++alfa)
355 for (
int beta=0; beta<Fnext_orbitals; ++beta)
367 for (
int alfa=0; alfa<Borbitals; ++alfa)
368 for (
int beta=0; beta<Bnext_orbitals; ++beta)
379 param2d InextPara = P.fill_array2d<
double>(
"Inext",
"InextPara", {Borbitals, Fnext_orbitals}, loc%Lcell);
380 labellist[loc].push_back(InextPara.label);
382 if (loc <
N_sites-1 or !
static_cast<bool>(boundary))
384 for (
int alfa=0; alfa<Borbitals; ++alfa)
385 for (
int beta=0; beta<Fnext_orbitals; ++beta)
392 param2d IprevPara = P.fill_array2d<
double>(
"Iprev",
"IprevPara", {Forbitals, Bnext_orbitals}, loc%Lcell);
393 labellist[loc].push_back(IprevPara.label);
395 if (lm1 <
N_sites-1 or !
static_cast<bool>(boundary))
397 for (
int alfa=0; alfa<Forbitals; ++alfa)
398 for (
int beta=0; beta<Bnext_orbitals; ++beta)
407 param2d tPrime = P.fill_array2d<
double>(
"tPrime",
"tPrime_array", {Forbitals, Fnextn_orbitals}, loc%Lcell);
408 labellist[loc].push_back(tPrime.label);
410 if (loc <
N_sites-2 or !
static_cast<bool>(boundary))
412 for (std::size_t alfa=0; alfa<Forbitals; ++alfa)
413 for (std::size_t beta=0; beta<Fnextn_orbitals; ++beta)
boost::rational< int > frac
std::string print_frac_nice(frac r)
size_t dim(const PivotMatrix0< Symmetry, Scalar, MpoScalar > &H)
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::SU2< Sym::SpinSU2 >, 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::SU2< Sym::SpinSU2 >, Sym::U1< Sym::ChargeU1 > > > >::type c(size_t locx, size_t locy=0, double factor=1.) const
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Sym::S1xS2< Sym::SU2< Sym::SpinSU2 >, Sym::U1< Sym::ChargeU1 > > > >::type S(size_t locx, size_t locy=0, double factor=1.) const
vector< SpinBase< Sym::S1xS2< Sym::SU2< Sym::SpinSU2 >, Sym::U1< Sym::ChargeU1 > > > > B
vector< FermionBase< Sym::S1xS2< Sym::SU2< Sym::SpinSU2 >, Sym::U1< Sym::ChargeU1 > > > > F
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Sym::S1xS2< Sym::SU2< Sym::SpinSU2 >, Sym::U1< Sym::ChargeU1 > > > >::type n(size_t locx, size_t locy=0) const
void finalize(const bool COMPRESS=true, const std::size_t power=1, const double tolerance=::mynumeric_limits< double >::epsilon())
void setLocBasis(const std::vector< std::vector< qType > > &q)
DMRG::VERBOSITY::OPTION VERB
void set_name(const std::string &label_in)
void precalc_TwoSiteData(bool FORCE=false)
void construct_from_pushlist(const PushType< OperatorType, CouplScalar > &pushlist, const std::vector< std::vector< std::string > > &labellist, size_t Lcell)
static SiteOperatorQ< Symmetry, MatrixType_ > outerprod(const SiteOperatorQ< Symmetry, MatrixType_ > &O1, const SiteOperatorQ< Symmetry, MatrixType_ > &O2, const qType &target)
static constexpr MODEL_FAMILY FAMILY
static qarray< 2 > singlet(int N)
static qarray< 2 > polaron(int L, int N=0)
static const map< string, any > defaults
Sym::S1xS2< Sym::SU2< Sym::SpinSU2 >, Sym::U1< Sym::ChargeU1 > > Symmetry
bool validate(qType qnum) const
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 const map< string, any > sweep_defaults
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixType
#define MAKE_TYPEDEFS(MODEL)