1#ifndef KONDOMODEL_SU2XSU2_H_
2#define KONDOMODEL_SU2XSU2_H_
10#include "Geometry2D.h"
16class KondoSU2xSU2 :
public Mpo<Sym::S1xS2<Sym::SU2<Sym::SpinSU2>,Sym::SU2<Sym::ChargeSU2> > ,double>,
17 public KondoObservables<Sym::S1xS2<Sym::SU2<Sym::SpinSU2>,Sym::SU2<Sym::ChargeSU2> > >,
23 typedef Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>
MatrixType;
49 template<
typename Symmetry_>
52 const BC boundary=BC::OPEN);
54 static const std::map<string,std::any>
defaults;
60 {
"t",1.}, {
"tRung",0.},
63 {
"V",0.}, {
"Vrung",0.},
64 {
"D",2ul}, {
"maxPower",2ul}, {
"CYLINDER",
false}, {
"Ly",1ul}, {
"LyF",1ul}
69 {
"max_alpha",100.}, {
"min_alpha",1.}, {
"lim_alpha",16ul}, {
"eps_svd",1e-7},
70 {
"Dincr_abs",5ul}, {
"Dincr_per",2ul}, {
"Dincr_rel",1.1},
71 {
"min_Nsv",0ul}, {
"max_Nrich",-1},
72 {
"max_halfsweeps",30ul}, {
"min_halfsweeps",10ul},
73 {
"Dinit",5ul}, {
"Qinit",6ul}, {
"Dlimit",200ul},
74 {
"tol_eigval",1e-6}, {
"tol_state",1e-5},
85 size_t Lcell = P.size();
87 for (
size_t l=0; l<
N_sites; ++l)
89 N_phys += P.get<
size_t>(
"LyF",l%Lcell);
90 setLocBasis((
B[l].get_basis().combine(
F[l].get_basis())).qloc(),l);
96 std::vector<std::vector<std::string>> labellist;
105template<
typename Symmetry_>
110 std::size_t Lcell = P.size();
114 for (std::size_t loc=0; loc<
N_sites; ++loc)
119 auto Gloc =
static_cast<SUB_LATTICE>(
static_cast<int>(pow(-1,loc)));
120 auto Glp1 =
static_cast<SUB_LATTICE>(
static_cast<int>(pow(-1,lp1)));
121 auto Glp2 =
static_cast<SUB_LATTICE>(
static_cast<int>(pow(-1,lp2)));
123 std::size_t Forbitals =
F[loc].orbitals();
124 std::size_t Fnext_orbitals =
F[lp1].orbitals();
125 std::size_t Fnextn_orbitals =
F[lp2].orbitals();
127 std::size_t Borbitals =
B[loc].orbitals();
128 std::size_t Bnext_orbitals =
B[lp1].orbitals();
129 std::size_t Bnextn_orbitals =
B[lp2].orbitals();
133 labellist[loc].push_back(Slabel.str());
135 auto push_full = [&
N_sites, &loc, &
B, &
F, &P, &pushlist, &labellist, &boundary] (
string xxxFull,
string label,
136 const vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > &first,
137 const vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > &last,
138 vector<double> factor,
bool FERMIONIC) ->
void
140 ArrayXXd Full = P.get<Eigen::ArrayXXd>(xxxFull);
141 vector<vector<std::pair<size_t,double> > > R = Geometry2D::rangeFormat(Full);
143 if (
static_cast<bool>(boundary)) {assert(R.size() ==
N_sites and
"Use an (N_sites)x(N_sites) hopping matrix for open BC!");}
144 else {assert(R.size() >= 2*
N_sites and
"Use at least a (2*N_sites)x(N_sites) hopping matrix for infinite BC!");}
146 for (
size_t j=0; j<first.size(); j++)
147 for (
size_t h=0; h<R[loc].size(); ++h)
149 size_t range = R[loc][h].first;
150 double value = R[loc][h].second;
154 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > ops(range+1);
156 for (
size_t i=1; i<range; ++i)
161 ops[range] = last[j][(loc+range)%
N_sites];
162 pushlist.push_back(std::make_tuple(loc, ops, factor[j] * value));
167 ss <<
label <<
"(" << Geometry2D::hoppingInfo(Full) <<
")";
168 labellist[loc].push_back(ss.str());
174 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > c_ranges(
N_sites);
175 for (
size_t i=0; i<
N_sites; i++)
177 auto Gi =
static_cast<SUB_LATTICE>(
static_cast<int>(pow(-1,i)));
181 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {cdag_sign_local};
182 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {c_ranges};
183 push_full(
"tFull",
"tᵢⱼ", first, last, {-std::sqrt(2.) * std::sqrt(2.)},
PROP::FERMIONIC);
189 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > T_ranges(
N_sites);
192 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {T_ranges};
193 push_full(
"Vfull",
"Vᵢⱼ", first, last, {std::sqrt(3.)},
PROP::BOSONIC);
199 param2d tPerp = P.fill_array2d<
double>(
"tRung",
"t",
"tPerp",Forbitals,loc%Lcell,P.get<
bool>(
"CYLINDER"));
200 labellist[loc].push_back(tPerp.label);
203 param2d Vperp = P.fill_array2d<
double>(
"Vrung",
"V",
"Vperp",Forbitals,loc%Lcell,P.get<
bool>(
"CYLINDER"));
204 labellist[loc].push_back(Vperp.label);
207 param1d U = P.fill_array1d<
double>(
"U",
"Uorb",Forbitals,loc%Lcell);
208 labellist[loc].push_back(U.label);
210 if (
F[loc].
dim() > 1)
212 OperatorType KondoHamiltonian({1,1},
B[loc].get_basis().combine(
F[loc].get_basis()));
214 ArrayXXd Jperp =
B[loc].ZeroHopping();
215 ArrayXXd Jperpsub =
F[loc].ZeroHopping();
218 KondoHamiltonian =
kroneckerProduct(
B[loc].Id(),
F[loc].HubbardHamiltonian(U.a,tPerp.a,Vperp.a,Jperpsub));
224 param1d J = P.fill_array1d<
double>(
"J",
"Jorb",Forbitals,loc%Lcell);
225 labellist[loc].push_back(J.label);
228 for (
int alfa=0; alfa<Forbitals; ++alfa)
230 assert(Borbitals == Forbitals and
"Can only do a Kondo ladder with the same amount of spins and fermionic orbitals in y-direction!");
240 auto [t,tPara,tlabel] = P.fill_array2d<
double>(
"t",
"tPara",{{Forbitals,
F[lp1].orbitals()}},loc%Lcell);
241 labellist[loc].push_back(tlabel);
243 if (loc <
N_sites-1 or !
static_cast<bool>(boundary))
245 for (
int alfa=0; alfa<Forbitals; ++alfa)
246 for (
int beta=0; beta<Fnext_orbitals; ++beta)
256 auto [V,Vpara,Vlabel] = P.fill_array2d<
double>(
"V",
"Vpara",{{Forbitals,
F[lp1].orbitals()}},loc%Lcell);
257 labellist[loc].push_back(Vlabel);
259 if (loc <
N_sites-1 or !
static_cast<bool>(boundary))
261 for (
int alfa=0; alfa<Forbitals; ++alfa)
262 for (
int beta=0; beta<Fnext_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::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::SU2< Sym::SpinSU2 >, Sym::SU2< Sym::ChargeSU2 > > > >::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::SU2< Sym::ChargeSU2 > > > >::type S(size_t locx, size_t locy=0, double factor=1.) const
vector< SpinBase< Sym::S1xS2< Sym::SU2< Sym::SpinSU2 >, Sym::SU2< Sym::ChargeSU2 > > > > B
std::enable_if< Dummy::IS_CHARGE_SU2(), Mpo< Sym::S1xS2< Sym::SU2< Sym::SpinSU2 >, Sym::SU2< Sym::ChargeSU2 > > > >::type Tdag(size_t locx, size_t locy=0, double factor=std::sqrt(3.)) const
vector< FermionBase< Sym::S1xS2< Sym::SU2< Sym::SpinSU2 >, Sym::SU2< Sym::ChargeSU2 > > > > F
std::enable_if< Dummy::IS_CHARGE_SU2(), Mpo< Sym::S1xS2< Sym::SU2< Sym::SpinSU2 >, Sym::SU2< Sym::ChargeSU2 > > > >::type T(size_t locx, size_t locy=0, double factor=1.) 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)
Sym::S1xS2< Sym::SU2< Sym::SpinSU2 >, Sym::SU2< Sym::ChargeSU2 > > Symmetry
static constexpr MODEL_FAMILY FAMILY
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixType
static qarray< 2 > singlet(int N)
static const std::map< string, std::any > defaults
SiteOperatorQ< Symmetry, MatrixType > OperatorType
static const map< string, any > sweep_defaults
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)
#define MAKE_TYPEDEFS(MODEL)