1#ifndef KONDOMODEL_U0XU1_H_
2#define KONDOMODEL_U0XU1_H_
38 typedef Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic>
MatrixType;
64 template<
typename Symmetry_>
67 const BC boundary=BC::OPEN);
77 static const std::map<string,std::any>
defaults;
91 {
"t",1.}, {
"tRung",0.}, {
"tPrime",0.}, {
"tPrimePrime",0.},
92 {
"J",1.}, {
"Jz",0.}, {
"U",0.},
93 {
"V",0.}, {
"Vrung",0.},
94 {
"Bz",0.}, {
"Bzsub",0.}, {
"Kz",0.}, {
"Bx",0.}, {
"Bxsub",0.}, {
"Kx",0.},
95 {
"Inext",0.}, {
"Iprev",0.}, {
"I3next",0.}, {
"I3prev",0.}, {
"I3loc",0.},
96 {
"D",2ul}, {
"maxPower",1ul}, {
"CYLINDER",
false}, {
"Ly",1ul}, {
"LyF",1ul},
97 {
"SEMIOPEN_LEFT",
false}, {
"SEMIOPEN_RIGHT",
false}, {
"mfactor",1},
98 {
"REMOVE_DOUBLE",
false}, {
"REMOVE_EMPTY",
false}, {
"REMOVE_UP",
false}, {
"REMOVE_DN",
false}, {
"mfactor",1}, {
"k",1}
103 {
"max_alpha",100.}, {
"min_alpha",1.}, {
"lim_alpha",11ul}, {
"eps_svd",1e-7},
104 {
"Mincr_abs",50ul}, {
"Mincr_per",2ul}, {
"Mincr_rel",1.1},
105 {
"min_Nsv",0ul}, {
"max_Nrich",-1},
106 {
"max_halfsweeps",30ul}, {
"min_halfsweeps",10ul},
107 {
"Minit",1ul}, {
"Qinit",1ul}, {
"Dlimit",10000ul},
108 {
"tol_eigval",1e-6}, {
"tol_state",1e-5},
119 size_t Lcell = P.size();
121 for (
size_t l=0; l<
N_sites; ++l)
123 N_phys += P.get<
size_t>(
"LyF",l%Lcell);
124 setLocBasis((
B[l].get_basis().combine(
F[l].get_basis())).qloc(),l);
132 std::vector<std::vector<std::string>> labellist;
141template<
typename Symmetry_>
146 std::size_t Lcell = P.size();
150 for (std::size_t loc=0; loc<
N_sites; ++loc)
152 size_t lm1 = (loc==0)?
N_sites-1 : loc-1;
162 std::size_t Fprev_orbitals =
F[lm1].orbitals();
163 std::size_t Forbitals =
F[loc].orbitals();
164 std::size_t Fnext_orbitals =
F[lp1].orbitals();
165 std::size_t Fnextn_orbitals =
F[lp2].orbitals();
166 std::size_t F3next_orbitals =
F[lp3].orbitals();
168 std::size_t Bprev_orbitals =
B[lm1].orbitals();
169 std::size_t Borbitals =
B[loc].orbitals();
170 std::size_t Bnext_orbitals =
B[lp1].orbitals();
171 std::size_t Bnextn_orbitals =
B[lp2].orbitals();
172 std::size_t B3next_orbitals =
B[lp3].orbitals();
177 labellist[loc].push_back(Slabel.str());
179 auto push_full = [&
N_sites, &loc, &
B, &
F, &P, &pushlist, &labellist, &boundary] (
string xxxFull,
string label,
180 const vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > &first,
181 const vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > &last,
182 vector<double> factor,
bool FERMIONIC) ->
void
184 ArrayXXd Full = P.get<Eigen::ArrayXXd>(xxxFull);
185 vector<vector<std::pair<size_t,double> > > R = Geometry2D::rangeFormat(Full);
187 if (
static_cast<bool>(boundary)) {assert(R.size() ==
N_sites and
"Use an (N_sites)x(N_sites) hopping matrix for open BC!");}
188 else {assert(R.size() >= 2*
N_sites and
"Use at least a (2*N_sites)x(N_sites) hopping matrix for infinite BC!");}
190 for (
size_t j=0; j<first.size(); j++)
191 for (
size_t h=0; h<R[loc].size(); ++h)
193 size_t range = R[loc][h].first;
194 double value = R[loc][h].second;
198 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > ops(range+1);
200 for (
size_t i=1; i<range; ++i)
205 ops[range] = last[j][(loc+range)%
N_sites];
206 pushlist.push_back(std::make_tuple(loc, ops, factor[j] * value));
211 ss <<
label <<
"(" << Geometry2D::hoppingInfo(Full) <<
")";
212 labellist[loc].push_back(ss.str());
218 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > cup_ranges(
N_sites);
220 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > cdn_ranges(
N_sites);
221 for (
size_t i=0; i<
N_sites; i++)
223 auto Gi =
static_cast<SUB_LATTICE>(
static_cast<int>(pow(-1,i)));
226 for (
size_t i=0; i<
N_sites; i++)
228 auto Gi =
static_cast<SUB_LATTICE>(
static_cast<int>(pow(-1,i)));
232 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {cdagup_sign_local, cdagdn_sign_local};
233 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {cup_ranges,cdn_ranges};
234 push_full(
"tFull",
"tᵢⱼ", first, last, {-std::sqrt(2.),- std::sqrt(2.)},
PROP::FERMIONIC);
240 param1d J = P.fill_array1d<
double>(
"J",
"Jorb", Forbitals, loc%Lcell);
241 labellist[loc].push_back(J.label);
244 param1d Jz = P.fill_array1d<
double>(
"Jz",
"Jzorb", Forbitals, loc%Lcell);
245 labellist[loc].push_back(Jz.label);
248 param2d tPerp = P.fill_array2d<
double>(
"tRung",
"t",
"tPerp", Forbitals, loc%Lcell, P.get<
bool>(
"CYLINDER"));
249 labellist[loc].push_back(tPerp.label);
252 param1d U = P.fill_array1d<
double>(
"U",
"Uorb", Forbitals, loc%Lcell);
253 labellist[loc].push_back(U.label);
256 param1d Bxsub = P.fill_array1d<
double>(
"Bxsub",
"Bxsuborb", Forbitals, loc%Lcell);
257 labellist[loc].push_back(Bxsub.label);
260 param1d Bx = P.fill_array1d<
double>(
"Bx",
"Bxorb", Borbitals, loc%Lcell);
261 labellist[loc].push_back(Bx.label);
264 param1d Kx = P.fill_array1d<
double>(
"Kx",
"Kxorb", Borbitals, loc%Lcell);
265 labellist[loc].push_back(Kx.label);
268 param1d Bzsub = P.fill_array1d<
double>(
"Bzsub",
"Bzsuborb", Forbitals, loc%Lcell);
269 labellist[loc].push_back(Bzsub.label);
272 param1d Bz = P.fill_array1d<
double>(
"Bz",
"Bzorb", Borbitals, loc%Lcell);
273 labellist[loc].push_back(Bz.label);
276 param1d Kz = P.fill_array1d<
double>(
"Kz",
"Kzorb", Borbitals, loc%Lcell);
277 labellist[loc].push_back(Kz.label);
279 ArrayXXd muPerp =
B[loc].ZeroHopping();
280 ArrayXXd nuPerp =
B[loc].ZeroHopping();
281 ArrayXXd Jxyperp =
B[loc].ZeroHopping();
282 ArrayXXd Jzperp =
B[loc].ZeroHopping();
283 ArrayXXd DyPerp =
B[loc].ZeroHopping();
286 auto KondoHamiltonian =
kroneckerProduct(
B[loc].HeisenbergHamiltonian(Jxyperp,Jzperp,Bz.a,Bx.a,muPerp,nuPerp,Kz.a,Kx.a,DyPerp),
F[loc].Id());
288 ArrayXXd Vperp =
F[loc].ZeroHopping();
289 ArrayXXd Jxysubperp =
F[loc].ZeroHopping();
290 ArrayXXd Jzsubperp =
F[loc].ZeroHopping();
293 KondoHamiltonian +=
kroneckerProduct(
B[loc].Id(),
F[loc].HubbardHamiltonian(U.a,tPerp.a,Vperp,Jzsubperp,Jxysubperp,Bzsub.a,Bxsub.a));
296 for (
int alfa=0; alfa<Forbitals; ++alfa)
300 assert(Borbitals == Forbitals and
"Can only do a Kondo ladder with the same amount of spins and fermionic orbitals in y-direction!");
315 param2d Vpara = P.fill_array2d<
double>(
"V",
"Vpara", {Forbitals, Fnext_orbitals}, loc%Lcell);
316 labellist[loc].push_back(Vpara.label);
321 param2d tPara = P.fill_array2d<
double>(
"t",
"tPara", {Forbitals, Fnext_orbitals}, loc%Lcell);
322 labellist[loc].push_back(tPara.label);
324 if (loc <
N_sites-1 or !
static_cast<bool>(boundary))
326 for (
int alfa=0; alfa<Forbitals; ++alfa)
327 for (
int beta=0; beta<Fnext_orbitals; ++beta)
335 auto Otmp_loc = PsiDagUp_loc * Sign_loc;
339 Otmp_loc = PsiDagDn_loc * Sign_loc;
347 param2d InextPara = P.fill_array2d<
double>(
"Inext",
"InextPara", {Borbitals, Fnext_orbitals}, loc%Lcell);
348 labellist[loc].push_back(InextPara.label);
350 if (loc <
N_sites-1 or !
static_cast<bool>(boundary))
352 for (std::size_t alfa=0; alfa<Borbitals; ++alfa)
353 for (std::size_t beta=0; beta<Fnext_orbitals; ++beta)
355 pushlist.push_back(std::make_tuple(loc,
358 0.5*InextPara(alfa,beta)));
359 pushlist.push_back(std::make_tuple(loc,
362 0.5*InextPara(alfa,beta)));
363 pushlist.push_back(std::make_tuple(loc,
366 InextPara(alfa,beta)));
370 param2d IprevPara = P.fill_array2d<
double>(
"Iprev",
"IprevPara", {Fprev_orbitals, Borbitals}, loc%Lcell);
371 labellist[loc].push_back(IprevPara.label);
373 if (lm1 <
N_sites-1 or !
static_cast<bool>(boundary))
375 for (std::size_t alfa=0; alfa<Fprev_orbitals; ++alfa)
376 for (std::size_t beta=0; beta<Borbitals; ++beta)
378 pushlist.push_back(std::make_tuple(lm1,
381 0.5*IprevPara(alfa,beta)));
382 pushlist.push_back(std::make_tuple(lm1,
385 0.5*IprevPara(alfa,beta)));
386 pushlist.push_back(std::make_tuple(lm1,
389 IprevPara(alfa,beta)));
395 param2d I3nextPara = P.fill_array2d<
double>(
"I3next",
"I3nextPara", {Forbitals, Fnext_orbitals}, loc%Lcell);
396 labellist[loc].push_back(I3nextPara.label);
398 if (loc <
N_sites-1 or !
static_cast<bool>(boundary))
400 for (std::size_t alfa=0; alfa<Forbitals; ++alfa)
401 for (std::size_t beta=0; beta<Fnext_orbitals; ++beta)
403 assert(Borbitals == 1);
411 auto Otmp_loc = Sm_PsiDagUp_loc * Sign_loc;
414 Otmp_loc = Sp_PsiDagDn_loc * Sign_loc;
417 pushlist.push_back(std::make_tuple(loc,
420 I3nextPara(alfa,beta)));
424 param2d I3prevPara = P.fill_array2d<
double>(
"I3prev",
"I3prevPara", {Fprev_orbitals, Forbitals}, loc%Lcell);
425 labellist[loc].push_back(I3prevPara.label);
427 if (lm1 <
N_sites-1 or !
static_cast<bool>(boundary))
429 for (std::size_t alfa=0; alfa<Fprev_orbitals; ++alfa)
430 for (std::size_t beta=0; beta<Forbitals; ++beta)
432 assert(Borbitals == 1);
440 auto Otmp_lm1 = Sm_PsiDagUp_lm1 * Sign_lm1;
443 Otmp_lm1 = Sp_PsiDagDn_lm1 * Sign_lm1;
446 pushlist.push_back(std::make_tuple(lm1,
449 I3prevPara(alfa,beta)));
454 if (!P.HAS(
"tFull") and P.HAS(
"tPrime",loc%Lcell))
456 param2d tPrime = P.fill_array2d<
double>(
"tPrime",
"tPrime_array", {Forbitals, F3next_orbitals}, loc%Lcell);
457 labellist[loc].push_back(tPrime.label);
459 if (loc <
N_sites-2 or !
static_cast<bool>(boundary))
464 for (std::size_t alfa=0; alfa<Forbitals; ++alfa)
465 for (std::size_t beta=0; beta<F3next_orbitals; ++beta)
473 auto Otmp_loc = PsiDagUp_loc * Sign_loc;
477 Otmp_loc = PsiDagDn_loc * Sign_loc;
484 if (!P.HAS(
"tFull") and P.HAS(
"tPrimePrime",loc%Lcell))
486 param2d tPrimePrime = P.fill_array2d<
double>(
"tPrimePrime",
"tPrimePrime_array", {Forbitals, F3next_orbitals}, loc%Lcell);
487 labellist[loc].push_back(tPrimePrime.label);
489 if (loc <
N_sites-3 or !
static_cast<bool>(boundary))
495 for (std::size_t alfa=0; alfa<Forbitals; ++alfa)
496 for (std::size_t beta=0; beta<F3next_orbitals; ++beta)
504 auto Otmp_loc = PsiDagUp_loc * Sign_loc;
508 Otmp_loc = PsiDagDn_loc * Sign_loc;
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::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::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::SU2< Sym::ChargeSU2 > > >::type S(size_t locx, size_t locy=0, double factor=1.) const
vector< SpinBase< Sym::SU2< Sym::ChargeSU2 > > > B
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Sym::SU2< Sym::ChargeSU2 > > >::type Sz(size_t locx, size_t locy=0) const
vector< FermionBase< Sym::SU2< Sym::ChargeSU2 > > > F
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Sym::SU2< Sym::ChargeSU2 > > >::type Scomp(SPINOP_LABEL Sa, 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 qarray< 1 > singlet(int N)
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixType
SiteOperatorQ< Symmetry, MatrixType > OperatorType
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)
Sym::SU2< Sym::ChargeSU2 > Symmetry
static constexpr MODEL_FAMILY FAMILY
static const map< string, any > sweep_defaults
#define MAKE_TYPEDEFS(MODEL)