1#ifndef STRAWBERRY_HUBBARDMODEL
2#define STRAWBERRY_HUBBARDMODEL
11#include "Geometry2D.h"
49class HubbardU1xU1 :
public Mpo<Sym::S1xS2<Sym::U1<Sym::SpinU1>,Sym::U1<Sym::ChargeU1> >,double>,
67 size_t Lcell =
P.size();
69 for (
size_t l=0; l<
N_sites; ++l)
N_phys +=
P.get<
size_t>(
"Ly",l%Lcell);
91 template<
typename Symmetry_>
96 static const std::map<string,std::any>
defaults;
101 {
"t",1.}, {
"tPrime",0.}, {
"tRung",1.},
102 {
"mu",0.}, {
"t0",0.},
103 {
"U",0.}, {
"Uph",0.},
104 {
"V",0.}, {
"Vrung",0.},
105 {
"Vxy",0.}, {
"Vz",0.},
107 {
"J",0.}, {
"Jperp",0.}, {
"J3site",0.},
108 {
"X",0.}, {
"Xperp",0.},
109 {
"REMOVE_DOUBLE",
false}, {
"REMOVE_EMPTY",
false}, {
"REMOVE_UP",
false}, {
"REMOVE_DN",
false}, {
"mfactor",1}, {
"k",0},
110 {
"maxPower",2ul}, {
"CYLINDER",
false}, {
"Ly",1ul}
120 size_t Lcell =
P.size();
122 for (
size_t l=0; l<
N_sites; ++l)
124 N_phys +=
P.get<
size_t>(
"Ly",l%Lcell);
128 param1d U =
P.fill_array1d<
double>(
"U",
"Uorb",
F[0].orbitals(), 0);
129 if (isfinite(U.a.sum()))
133 else if (P.HAS_ANY_OF({
"J",
"J3site"}))
143 std::vector<std::vector<std::string>> labellist;
151template<
typename Symmetry_>
155 std::size_t Lcell =
P.size();
159 for (std::size_t loc=0; loc<
N_sites; ++loc)
164 std::size_t orbitals =
F[loc].orbitals();
165 std::size_t next_orbitals =
F[lp1].orbitals();
166 std::size_t nextn_orbitals =
F[lp2].orbitals();
169 ss <<
"Ly=" <<
P.get<
size_t>(
"Ly",loc%Lcell);
170 labellist[loc].push_back(ss.str());
172 auto push_full = [&
N_sites, &loc, &
F, &
P, &pushlist, &labellist, &boundary] (
string xxxFull,
string label,
173 const vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > &first,
174 const vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > &last,
175 vector<double> factor,
bool FERMIONIC) ->
void
177 ArrayXXd Full =
P.get<Eigen::ArrayXXd>(xxxFull);
178 vector<vector<std::pair<size_t,double> > > R = Geometry2D::rangeFormat(Full);
180 if (
static_cast<bool>(boundary)) {assert(R.size() ==
N_sites and
"Use an (N_sites)x(N_sites) hopping matrix for open BC!");}
181 else {assert(R.size() >= 2*
N_sites and
"Use at least a (2*N_sites)x(N_sites) hopping matrix for infinite BC!");}
183 for (
size_t j=0; j<first.size(); j++)
184 for (
size_t h=0; h<R[loc].size(); ++h)
186 size_t range = R[loc][h].first;
187 double value = R[loc][h].second;
191 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > ops(range+1);
193 for (
size_t i=1; i<range; ++i)
195 if (FERMIONIC) {ops[i] =
F[(loc+i)%
N_sites].sign();}
198 ops[range] = last[j][(loc+range)%
N_sites];
199 pushlist.push_back(std::make_tuple(loc, ops, factor[j] * value));
204 ss <<
label <<
"(" << Geometry2D::hoppingInfo(Full) <<
")";
205 labellist[loc].push_back(ss.str());
215 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > cUP_ranges(
N_sites);
for (
size_t i=0; i<
N_sites; ++i) {cUP_ranges[i] =
F[i].c(
UP,0);}
216 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > cdagUP_ranges(
N_sites);
for (
size_t i=0; i<
N_sites; ++i) {cdagUP_ranges[i] =
F[i].cdag(
UP,0);}
217 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > cDN_ranges(
N_sites);
for (
size_t i=0; i<
N_sites; ++i) {cDN_ranges[i] =
F[i].c(
DN,0);}
218 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > cdagDN_ranges(
N_sites);
for (
size_t i=0; i<
N_sites; ++i) {cdagDN_ranges[i] =
F[i].cdag(
DN,0);}
220 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > frst {cdagUP_sign_local, cUP_sign_local, cdagDN_sign_local, cDN_sign_local};
221 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {cUP_ranges, cdagUP_ranges, cDN_ranges, cdagDN_ranges};
222 push_full(
"tFull",
"tᵢⱼ", frst, last, {-1., +1., -1., +1.},
PROP::FERMIONIC);
225 if (
P.HAS(
"Vxyfull"))
227 auto Gloc =
static_cast<SUB_LATTICE>(
static_cast<int>(pow(-1,loc)));
228 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {
F[loc].Tp(0,Gloc),
F[loc].Tm(0,Gloc)};
229 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Tp_ranges(
N_sites);
230 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Tm_ranges(
N_sites);
231 for (
size_t i=0; i<
N_sites; i++)
233 auto Gi =
static_cast<SUB_LATTICE>(
static_cast<int>(pow(-1,i)));
234 Tp_ranges[i] =
F[i].Tp(0,Gi);
235 Tm_ranges[i] =
F[i].Tm(0,Gi);
238 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {Tm_ranges, Tp_ranges};
239 push_full(
"Vxyfull",
"Vxyᵢⱼ", first, last, {0.5,0.5},
PROP::BOSONIC);
244 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {
F[loc].Tz(0)};
245 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Tz_ranges(
N_sites);
246 for (
size_t i=0; i<
N_sites; i++)
248 Tz_ranges[i] =
F[i].Tz(0);
251 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {Tz_ranges};
252 push_full(
"Vzfull",
"Vzᵢⱼ", first, last, {1.},
PROP::BOSONIC);
257 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {
F[loc].tz(0)};
258 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > tz_ranges(
N_sites);
259 for (
size_t i=0; i<
N_sites; i++)
261 tz_ranges[i] =
F[i].tz(0);
264 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {tz_ranges};
265 push_full(
"vzfull",
"vzᵢⱼ", first, last, {1.},
PROP::BOSONIC);
268 if (
P.HAS(
"VextFull"))
270 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {
F[loc].n(0)};
271 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);}
272 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {n_ranges};
273 push_full(
"VextFull",
"Vextᵢⱼ", first, last, {1.},
PROP::BOSONIC);
278 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {
F[loc].Sp(0),
F[loc].Sm(0),
F[loc].Sz(0)};
279 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Sp_ranges(
N_sites);
280 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Sm_ranges(
N_sites);
281 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Sz_ranges(
N_sites);
282 for (
size_t i=0; i<
N_sites; i++)
284 Sp_ranges[i] =
F[i].Sp(0);
285 Sm_ranges[i] =
F[i].Sm(0);
286 Sz_ranges[i] =
F[i].Sz(0);
289 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {Sm_ranges, Sp_ranges, Sz_ranges};
290 push_full(
"Jfull",
"Jᵢⱼ", first, last, {0.5,0.5,1.},
PROP::BOSONIC);
295 param1d U =
P.fill_array1d<
double>(
"U",
"Uorb", orbitals, loc%Lcell);
296 param1d Uph =
P.fill_array1d<
double>(
"Uph",
"Uorb", orbitals, loc%Lcell);
297 param1d t0 =
P.fill_array1d<
double>(
"t0",
"t0orb", orbitals, loc%Lcell);
298 param1d mu =
P.fill_array1d<
double>(
"mu",
"muorb", orbitals, loc%Lcell);
299 param1d Bz =
P.fill_array1d<
double>(
"Bz",
"Bzorb", orbitals, loc%Lcell);
300 param2d tperp =
P.fill_array2d<
double>(
"tRung",
"t",
"tPerp", orbitals, loc%Lcell,
P.get<
bool>(
"CYLINDER"));
301 param2d Vperp =
P.fill_array2d<
double>(
"Vrung",
"V",
"Vperp", orbitals, loc%Lcell,
P.get<
bool>(
"CYLINDER"));
302 param2d Vxyperp =
P.fill_array2d<
double>(
"Vxyrung",
"Vxy",
"Vxyperp", orbitals, loc%Lcell,
P.get<
bool>(
"CYLINDER"));
303 param2d Vzperp =
P.fill_array2d<
double>(
"Vzrung",
"Vz",
"Vzperp", orbitals, loc%Lcell,
P.get<
bool>(
"CYLINDER"));
304 param2d Jperp =
P.fill_array2d<
double>(
"Jrung",
"J",
"Jperp", orbitals, loc%Lcell,
P.get<
bool>(
"CYLINDER"));
306 labellist[loc].push_back(U.label);
307 labellist[loc].push_back(Uph.label);
308 labellist[loc].push_back(t0.label);
309 labellist[loc].push_back(mu.label);
310 labellist[loc].push_back(Bz.label);
311 labellist[loc].push_back(tperp.label);
312 labellist[loc].push_back(Vperp.label);
313 labellist[loc].push_back(Jperp.label);
314 ArrayXd C_array =
F[loc].ZeroField();
321 F[loc].
template HubbardHamiltonian<double>(U.a, Uph.a, t0.a-mu.a, Bz.a, tperp.a, Vperp.a, Vzperp.a, Vxyperp.a, Jperp.a, Jperp.a, C_array)
323 pushlist.push_back(std::make_tuple(loc, Hloc, 1.));
327 param2d tpara =
P.fill_array2d<
double>(
"t",
"tPara", {orbitals, next_orbitals}, loc%Lcell);
328 param2d Vpara =
P.fill_array2d<
double>(
"V",
"Vpara", {orbitals, next_orbitals}, loc%Lcell);
329 param2d Jpara =
P.fill_array2d<
double>(
"J",
"Jpara", {orbitals, next_orbitals}, loc%Lcell);
330 param2d Xpara =
P.fill_array2d<
double>(
"X",
"Xpara", {orbitals, next_orbitals}, loc%Lcell);
331 param2d Vxypara =
P.fill_array2d<
double>(
"Vxy",
"Vxypara", {orbitals, next_orbitals}, loc%Lcell);
332 param2d Vzpara =
P.fill_array2d<
double>(
"Vz",
"Vzpara", {orbitals, next_orbitals}, loc%Lcell);
334 labellist[loc].push_back(tpara.label);
335 labellist[loc].push_back(Vpara.label);
336 labellist[loc].push_back(Jpara.label);
337 labellist[loc].push_back(Xpara.label);
338 labellist[loc].push_back(Vxypara.label);
339 labellist[loc].push_back(Vzpara.label);
341 if (loc <
N_sites-1 or !
static_cast<bool>(boundary))
343 for (std::size_t alfa=0; alfa<orbitals; ++alfa)
344 for (std::size_t beta=0; beta<next_orbitals; ++beta)
349 if (tpara(alfa,beta) != 0.)
361 if (Vpara(alfa,beta) != 0.)
370 if (Jpara(alfa,beta) != 0.)
398 if (Xpara(alfa,beta) != 0.)
401 (
F[lp1].
c(
UP,beta) * (
F[lp1].Id()-2.*
F[lp1].n(
DN,beta)))),
404 (
F[lp1].
c(
UP,beta) *
F[lp1].n(
DN,beta))),
407 (
F[lp1].
c(
DN,beta) * (
F[lp1].
Id()-2.*
F[lp1].
n(
UP,beta)))),
410 (
F[lp1].
c(
DN,beta) *
F[lp1].
n(
UP,beta))),
429 if (!
P.HAS(
"Vxyfull"))
431 if (Vxypara(alfa,beta) != 0.)
437 if (!
P.HAS(
"Vzfull"))
439 if (Vzpara(alfa,beta) != 0.)
448 param2d tPrime =
P.fill_array2d<
double>(
"tPrime",
"tPrime_array", {orbitals, nextn_orbitals}, loc%Lcell);
449 labellist[loc].push_back(tPrime.label);
450 if (loc <
N_sites-2 or !
static_cast<bool>(boundary))
452 for (std::size_t alfa=0; alfa<orbitals; ++alfa)
453 for (std::size_t beta=0; beta<nextn_orbitals; ++beta)
455 if (tPrime(alfa,beta) != 0.)
459 F[lp2].c(
UP,beta)), -tPrime(alfa,beta)));
462 F[lp2].c(
DN,beta)), -tPrime(alfa,beta)));
465 F[lp2].cdag(
UP,beta)), +tPrime(alfa,beta)));
468 F[lp2].cdag(
DN,beta)), +tPrime(alfa,beta)));
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, 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::U1< Sym::SpinU1 >, Sym::U1< Sym::ChargeU1 > >, double > >::type P(size_t locx1, size_t locx2, size_t locy1=0, size_t locy2=0) const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::U1< Sym::ChargeU1 > >, double > >::type Sz(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 > >, double > >::type Sp(size_t locx, size_t locy=0) const
Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::U1< Sym::ChargeU1 > >, double > Id() const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::U1< Sym::ChargeU1 > >, double > >::type Sm(size_t locx, size_t locy=0) const
std::enable_if<!Dummy::IS_CHARGE_SU2(), Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::U1< Sym::ChargeU1 > >, double > >::type cc(size_t locx, size_t locy=0) const
std::enable_if<!Dummy::IS_CHARGE_SU2(), Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::U1< Sym::ChargeU1 > >, double > >::type Tz(size_t locx, size_t locy=0) const
std::enable_if<!Dummy::IS_CHARGE_SU2(), Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::U1< Sym::ChargeU1 > >, double > >::type cdagcdag(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 > >, double > >::type n(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 > >, double > >::type cdag(size_t locx, size_t locy=0, double factor=std::sqrt(2.)) 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)
static std::vector< T > get_N_site_interaction(T const &Op0, Operator const &... Ops)
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)
Hubbard model with U(1) symmetries. MPO representation of the Hubbard model.
HubbardU1xU1(Mpo< Symmetry > &Mpo_input, const vector< Param > ¶ms)
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 int spinfac
Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::U1< Sym::ChargeU1 > > Symmetry
static const std::map< string, std::any > defaults
static constexpr MODEL_FAMILY FAMILY
static qarray< 2 > singlet(int N=0, int L=0)
#define MAKE_TYPEDEFS(MODEL)