1#ifndef HUBBARDMODELSU2XU1_H_
2#define HUBBARDMODELSU2XU1_H_
15#include "Geometry2D.h"
44class HubbardSU2xU1 :
public Mpo<Sym::S1xS2<Sym::SU2<Sym::SpinSU2>,Sym::U1<Sym::ChargeU1> > ,double>,
45 public HubbardObservables<Sym::S1xS2<Sym::SU2<Sym::SpinSU2>,Sym::U1<Sym::ChargeU1> > >,
52 typedef Eigen::Matrix<
double,Eigen::Dynamic,Eigen::Dynamic>
MatrixType;
71 size_t Lcell =
P.size();
73 for (
size_t l=0; l<
N_sites; ++l)
N_phys +=
P.get<
size_t>(
"Ly",l%Lcell);
91 template<
typename Symmetry_>
94 const BC boundary=BC::OPEN);
108 {
"t",1.}, {
"tPrime",0.}, {
"tRung",1.}, {
"tPrimePrime",0.},
109 {
"mu",0.}, {
"t0",0.},
110 {
"U",0.}, {
"Uph",0.},
111 {
"V",0.}, {
"Vext",0.}, {
"Vrung",0.},
112 {
"Vz",0.}, {
"Vzrung",0.}, {
"Vxy",0.}, {
"Vxyrung",0.},
113 {
"J",0.}, {
"Jperp",0.},
114 {
"X",0.}, {
"Xrung",0.},
115 {
"REMOVE_DOUBLE",
false}, {
"REMOVE_EMPTY",
false}, {
"REMOVE_UP",
false}, {
"REMOVE_DN",
false}, {
"mfactor",1}, {
"k",0},
116 {
"maxPower",2ul}, {
"CYLINDER",
false}, {
"Ly",1ul}
121 {
"max_alpha",100.}, {
"min_alpha",1.}, {
"lim_alpha",21ul}, {
"eps_svd",1e-7},
122 {
"Mincr_abs", 50ul}, {
"Mincr_per", 4ul}, {
"Mincr_rel", 1.1},
123 {
"min_Nsv",0ul}, {
"max_Nrich",-1},
124 {
"max_halfsweeps",24ul}, {
"min_halfsweeps",1ul},
125 {
"Minit",2ul}, {
"Qinit",2ul}, {
"Mlimit",1000ul},
126 {
"tol_eigval",1e-7}, {
"tol_state",1e-6},
136 ParamHandler P(params,defaults);
137 size_t Lcell = P.size();
139 for (
size_t l=0; l<N_sites; ++l)
141 N_phys += P.get<
size_t>(
"Ly",l%Lcell);
142 setLocBasis(F[l].get_basis().qloc(),l);
145 param1d U = P.fill_array1d<
double>(
"U",
"Uorb", F[0].orbitals(), 0);
146 if (isfinite(U.a.sum()))
148 this->set_name(
"Hubbard");
152 this->set_name(
"U=∞-Hubbard");
156 std::vector<std::vector<std::string>> labellist;
157 set_operators(F, P, pushlist, labellist, boundary);
159 this->construct_from_pushlist(pushlist, labellist, Lcell);
162 this->precalc_TwoSiteData();
165template<
typename Symmetry_>
169 std::size_t Lcell =
P.size();
173 for (std::size_t loc=0; loc<
N_sites; ++loc)
179 std::size_t orbitals =
F[loc].orbitals();
180 std::size_t next_orbitals =
F[lp1].orbitals();
181 std::size_t nextn_orbitals =
F[lp2].orbitals();
182 std::size_t nnextn_orbitals =
F[lp3].orbitals();
185 ss <<
"Ly=" <<
P.get<
size_t>(
"Ly",loc%Lcell);
186 labellist[loc].push_back(ss.str());
188 auto push_full = [&
N_sites, &loc, &
F, &
P, &pushlist, &labellist, &boundary] (
string xxxFull,
string label,
189 const vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > &first,
190 const vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > &last,
191 vector<double> factor,
bool FERMIONIC) ->
void
193 ArrayXXd Full =
P.get<Eigen::ArrayXXd>(xxxFull);
194 vector<vector<std::pair<size_t,double> > > R = Geometry2D::rangeFormat(Full);
196 if (
static_cast<bool>(boundary)) {assert(R.size() ==
N_sites and
"Use an (N_sites)x(N_sites) hopping matrix for open BC!");}
197 else {assert(R.size() >= 2*
N_sites and
"Use at least a (2*N_sites)x(N_sites) hopping matrix for infinite BC!");}
199 for (
size_t j=0; j<first.size(); j++)
200 for (
size_t h=0; h<R[loc].size(); ++h)
202 size_t range = R[loc][h].first;
203 double value = R[loc][h].second;
207 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > ops(range+1);
209 for (
size_t i=1; i<range; ++i)
211 if (FERMIONIC) {ops[i] =
F[(loc+i)%
N_sites].sign();}
214 ops[range] = last[j][(loc+range)%
N_sites];
215 pushlist.push_back(std::make_tuple(loc, ops, factor[j] * value));
220 ss <<
label <<
"(" << Geometry2D::hoppingInfo(Full) <<
")";
221 labellist[loc].push_back(ss.str());
228 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > c_ranges(
N_sites);
for (
size_t i=0; i<
N_sites; i++) {c_ranges[i] =
F[i].c(0);}
229 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > cdag_ranges(
N_sites);
for (
size_t i=0; i<
N_sites; i++) {cdag_ranges[i] =
F[i].cdag(0);}
231 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {cdag_sign_local,c_sign_local};
232 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {c_ranges,cdag_ranges};
233 push_full(
"tFull",
"tᵢⱼ", first, last, {-std::sqrt(2.), -std::sqrt(2.)},
PROP::FERMIONIC);
239 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > c_ranges(
N_sites);
for (
size_t i=0; i<
N_sites; i++) {c_ranges[i] =
F[i].c(1);}
240 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > cdag_ranges(
N_sites);
for (
size_t i=0; i<
N_sites; i++) {cdag_ranges[i] =
F[i].cdag(1);}
242 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {cdag_sign_local,c_sign_local};
243 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {c_ranges,cdag_ranges};
244 push_full(
"tFullA",
"tAᵢⱼ", first, last, {-std::sqrt(2.), -std::sqrt(2.)},
PROP::FERMIONIC);
248 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {
F[loc].Tz(0)};
249 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Tz_ranges(
N_sites);
for (
size_t i=0; i<
N_sites; i++) {Tz_ranges[i] =
F[i].Tz(0);}
250 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {Tz_ranges};
251 push_full(
"Vzfull",
"Vzᵢⱼ", first, last, {1.},
PROP::BOSONIC);
253 if (
P.HAS(
"Vxyfull"))
255 auto Gloc =
static_cast<SUB_LATTICE>(
static_cast<int>(pow(-1,loc)));
256 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {
F[loc].Tp(0,Gloc),
F[loc].Tm(0,Gloc)};
257 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Tp_ranges(
N_sites);
258 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Tm_ranges(
N_sites);
259 for (
size_t i=0; i<
N_sites; i++)
260 {
auto Gi =
static_cast<SUB_LATTICE>(
static_cast<int>(pow(-1,i))); Tp_ranges[i] =
F[i].Tp(0,Gi); Tm_ranges[i] =
F[i].Tm(0,Gi);}
262 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {Tm_ranges, Tp_ranges};
263 push_full(
"Vxyfull",
"Vxyᵢⱼ", first, last, {0.5,0.5},
PROP::BOSONIC);
265 if (
P.HAS(
"VextFull"))
267 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {
F[loc].n(0)};
268 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > n_ranges(
N_sites);
for (
size_t i=0; i<
N_sites; i++) {n_ranges[i] =
F[i].n(0);}
269 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {n_ranges};
270 push_full(
"VextFull",
"Vextᵢⱼ", first, last, {1.},
PROP::BOSONIC);
274 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {
F[loc].Sdag(0)};
275 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > S_ranges(
N_sites);
for (
size_t i=0; i<
N_sites; i++) {S_ranges[i] =
F[i].S(0);}
276 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {S_ranges};
277 push_full(
"Jfull",
"Jᵢⱼ", first, last, {std::sqrt(3.)},
PROP::BOSONIC);
284 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > PsiLran(
N_sites);
for(
size_t i=0; i<
N_sites; i++) {PsiLran[i] = (
F[i].ns() *
F[i].c());}
285 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > PsiRran(
N_sites);
for(
size_t i=0; i<
N_sites; i++) {PsiRran[i] = (
F[i].c() *
F[i].ns());}
290 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > PsidagLran(
N_sites);
for(
size_t i=0; i<
N_sites; i++) {PsidagLran[i] = (
F[i].cdag() *
F[i].ns());}
291 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > PsidagRran(
N_sites);
for(
size_t i=0; i<
N_sites; i++) {PsidagRran[i] = (
F[i].ns() *
F[i].cdag());}
293 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {PsidagLloc,PsidagRloc,PsiLloc,PsiRloc};
294 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {PsiRran,PsiLran,PsidagRran,PsidagLran};
295 push_full(
"Xfull",
"Xᵢⱼ", first, last, {-std::sqrt(2.), -std::sqrt(2.), -std::sqrt(2.), -std::sqrt(2.)},
PROP::FERMIONIC);
299 ArrayXXd Bfull =
P.get<Eigen::ArrayXXd>(
"Bfull");
300 vector<vector<std::pair<size_t,double> > > R = Geometry2D::rangeFormat(Bfull);
302 if (
static_cast<bool>(boundary)) {assert(R.size() ==
N_sites and
"Use an (N_sites)x(N_sites) hopping matrix for open BC!");}
303 else {assert(R.size() >= 2*
N_sites and
"Use at least a (2*N_sites)x(N_sites) hopping matrix for infinite BC!");}
305 for (
size_t h=0; h<R[loc].size(); ++h)
307 size_t range = R[loc][h].first;
308 double value = R[loc][h].second;
309 cout <<
"range=" << range <<
", value=" << value << endl;
313 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > ops(range+2);
314 ops[0] =
F[loc].cdag(0) *
F[loc].sign();
317 ops[1] =
F[loc+1].cdag(0);
318 for (
size_t i=2; i<=range-1; ++i)
323 ops[range+1] =
F[(loc+range+1)%
N_sites].
c(0);
324 pushlist.push_back(std::make_tuple(loc, ops, -value));
329 for (
size_t h=0; h<R[loc].size(); ++h)
331 size_t range = R[loc][h].first;
332 double value = R[loc][h].second;
336 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > ops(range+2);
337 ops[0] =
F[loc].c(0) *
F[loc].sign();
340 ops[1] =
F[loc+1].c(0);
341 for (
size_t i=2; i<=range-1; ++i)
347 pushlist.push_back(std::make_tuple(loc, ops, -value));
355 param1d U =
P.fill_array1d<
double>(
"U",
"Uorb", orbitals, loc%Lcell);
356 param1d Uph =
P.fill_array1d<
double>(
"Uph",
"Uphorb", orbitals, loc%Lcell);
357 param1d t0 =
P.fill_array1d<
double>(
"t0",
"t0orb", orbitals, loc%Lcell);
358 param1d mu =
P.fill_array1d<
double>(
"mu",
"muorb", orbitals, loc%Lcell);
359 param2d tperp =
P.fill_array2d<
double>(
"tRung",
"t",
"tPerp", orbitals, loc%Lcell,
P.get<
bool>(
"CYLINDER"));
360 param2d Vperp =
P.fill_array2d<
double>(
"VRung",
"V",
"VPerp", orbitals, loc%Lcell,
P.get<
bool>(
"CYLINDER"));
361 param2d Vzperp =
P.fill_array2d<
double>(
"VzRung",
"Vz",
"VzPerp", orbitals, loc%Lcell,
P.get<
bool>(
"CYLINDER"));
362 param2d Vxyperp =
P.fill_array2d<
double>(
"VxyRung",
"Vxy",
"VxyPerp", orbitals, loc%Lcell,
P.get<
bool>(
"CYLINDER"));
363 param2d Jperp =
P.fill_array2d<
double>(
"JRung",
"J",
"JPerp", orbitals, loc%Lcell,
P.get<
bool>(
"CYLINDER"));
365 labellist[loc].push_back(U.label);
366 labellist[loc].push_back(Uph.label);
367 labellist[loc].push_back(t0.label);
368 labellist[loc].push_back(mu.label);
369 labellist[loc].push_back(tperp.label);
370 labellist[loc].push_back(Vperp.label);
371 labellist[loc].push_back(Vzperp.label);
372 labellist[loc].push_back(Vxyperp.label);
373 labellist[loc].push_back(Jperp.label);
377 F[loc].
template HubbardHamiltonian<double>(U.a, Uph.a, t0.a-mu.a, tperp.a, Vperp.a, Vzperp.a, Vxyperp.a, Jperp.a)
379 pushlist.push_back(std::make_tuple(loc, Hloc, 1.));
383 if (!
P.HAS(
"tFull") and !
P.HAS(
"Vzfull") and !
P.HAS(
"Vxyfull") and !
P.HAS(
"Jfull") and !
P.HAS(
"Xfull"))
385 param2d tpara =
P.fill_array2d<
double>(
"t",
"tPara", {orbitals, next_orbitals}, loc%Lcell);
386 param2d Vpara =
P.fill_array2d<
double>(
"V",
"Vpara", {orbitals, next_orbitals}, loc%Lcell);
387 param2d Vzpara =
P.fill_array2d<
double>(
"Vz",
"Vzpara", {orbitals, next_orbitals}, loc%Lcell);
388 param2d Vxypara =
P.fill_array2d<
double>(
"Vxy",
"Vxypara", {orbitals, next_orbitals}, loc%Lcell);
389 param2d Jpara =
P.fill_array2d<
double>(
"J",
"Jpara", {orbitals, next_orbitals}, loc%Lcell);
390 param2d Xpara =
P.fill_array2d<
double>(
"X",
"Xpara", {orbitals, next_orbitals}, loc%Lcell);
392 labellist[loc].push_back(tpara.label);
393 labellist[loc].push_back(Vpara.label);
394 labellist[loc].push_back(Vzpara.label);
395 labellist[loc].push_back(Vxypara.label);
396 labellist[loc].push_back(Jpara.label);
397 labellist[loc].push_back(Xpara.label);
399 if (loc <
N_sites-1 or !
static_cast<bool>(boundary))
401 for (std::size_t alfa=0; alfa<orbitals; ++alfa)
402 for (std::size_t beta=0; beta<next_orbitals; ++beta)
416 auto Gloc =
static_cast<SUB_LATTICE>(
static_cast<int>(pow(-1,loc)));
417 auto Glp1 =
static_cast<SUB_LATTICE>(
static_cast<int>(pow(-1,lp1)));
463 param2d tPrime =
P.fill_array2d<
double>(
"tPrime",
"tPrime_array", {orbitals, nextn_orbitals}, loc%Lcell);
464 labellist[loc].push_back(tPrime.label);
466 if (loc <
N_sites-2 or !
static_cast<bool>(boundary))
468 for (std::size_t alfa=0; alfa<orbitals; ++alfa)
469 for (std::size_t beta=0; beta<nextn_orbitals; ++beta)
479 pushlist.push_back(std::make_tuple(loc,
481 -std::sqrt(2.)*tPrime(alfa,beta)));
482 pushlist.push_back(std::make_tuple(loc,
484 -std::sqrt(2.)*tPrime(alfa,beta)));
492 param2d tPrimePrime =
P.fill_array2d<
double>(
"tPrimePrime",
"tPrimePrime_array", {orbitals, nnextn_orbitals}, loc%Lcell);
493 labellist[loc].push_back(tPrimePrime.label);
495 if (loc <
N_sites-3 or !
static_cast<bool>(boundary))
500 for (std::size_t alfa=0; alfa<orbitals; ++alfa)
501 for (std::size_t beta=0; beta<nnextn_orbitals; ++beta)
509 pushlist.push_back(std::make_tuple(loc,
511 -std::sqrt(2.)*tPrimePrime(alfa,beta)));
512 pushlist.push_back(std::make_tuple(loc,
514 -std::sqrt(2.)*tPrimePrime(alfa,beta)));
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Sym::S1xS2< Sym::SU2< Sym::SpinSU2 >, Sym::U1< Sym::ChargeU1 > >, double > >::type c(size_t locx, size_t locy=0, double factor=1.) const
std::enable_if< Dummy::IS_SPIN_SU2() and!Dummy::IS_CHARGE_SU2(), Mpo< Sym::S1xS2< Sym::SU2< Sym::SpinSU2 >, Sym::U1< Sym::ChargeU1 > >, double > >::type P(size_t locx1, size_t locx2, size_t locy1=0, size_t locy2=0) const
Mpo< Sym::S1xS2< Sym::SU2< Sym::SpinSU2 >, Sym::U1< Sym::ChargeU1 > >, double > ns(size_t locx, size_t locy=0) const
Mpo< Sym::S1xS2< Sym::SU2< Sym::SpinSU2 >, Sym::U1< Sym::ChargeU1 > >, double > Id() const
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 > >, double > >::type cdag(size_t locx, size_t locy=0, double factor=std::sqrt(2.)) const
DMRG::VERBOSITY::OPTION VERB
static std::vector< T > get_N_site_interaction(T const &Op0, Operator const &... Ops)
void precalc_TwoSiteData(bool FORCE=false)
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixType
HubbardSU2xU1(Mpo< Symmetry > &Mpo_input, const vector< Param > ¶ms)
static constexpr int spinfac
Sym::S1xS2< Sym::SU2< Sym::SpinSU2 >, Sym::U1< Sym::ChargeU1 > > Symmetry
static const map< string, any > defaults
static const map< string, any > sweep_defaults
static qarray< 2 > singlet(int N=0, int L=0)
static void set_operators(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 constexpr MODEL_FAMILY FAMILY
#define MAKE_TYPEDEFS(MODEL)
void finalize(bool PRINT_STATS=false)