VMPS++
Loading...
Searching...
No Matches
PeierlsHubbardU1xSU2.h
Go to the documentation of this file.
1#ifndef HUBBARDMODELU1XSU2CHARGE_H_
2#define HUBBARDMODELU1XSU2CHARGE_H_
3
5#include "symmetry/SU2.h"
6#include "bases/FermionBase.h"
8#include "Mpo.h"
9#include "ParamReturner.h"
10#include "Geometry2D.h" // from TOOLS
11
12namespace VMPS
13{
14class PeierlsHubbardU1xSU2 : public Mpo<Sym::S1xS2<Sym::U1<Sym::SpinU1>,Sym::SU2<Sym::ChargeSU2> >,complex<double> >,
15 public HubbardObservables<Sym::S1xS2<Sym::U1<Sym::SpinU1>,Sym::SU2<Sym::ChargeSU2> >,complex<double> >,
16 public ParamReturner
17{
18public:
19
22 typedef Eigen::Matrix<complex<double>,Eigen::Dynamic,Eigen::Dynamic> MatrixType;
24
25private:
26
27 typedef Eigen::Index Index;
29
30public:
31
34
35 PeierlsHubbardU1xSU2(Mpo<Symmetry, complex<double> > &Mpo_input, const vector<Param> &params)
36 :Mpo<Symmetry,complex<double> >(Mpo_input),
39 {
40 ParamHandler P(params,PeierlsHubbardU1xSU2::defaults);
41 size_t Lcell = P.size();
42 N_phys = 0;
43 for (size_t l=0; l<N_sites; ++l) N_phys += P.get<size_t>("Ly",l%Lcell);
44 this->calc(P.get<size_t>("maxPower"));
45 this->precalc_TwoSiteData();
46 this->HERMITIAN = true;
47 this->HAMILTONIAN = true;
48 };
49
50 PeierlsHubbardU1xSU2 (const size_t &L, const vector<Param> &params, const BC &boundary=BC::OPEN, const DMRG::VERBOSITY::OPTION &VERB=DMRG::VERBOSITY::OPTION::ON_EXIT);
52
53 template<typename Symmetry_>
54 static void set_operators (const std::vector<FermionBase<Symmetry_> > &F, const vector<SUB_LATTICE> &G, const ParamHandler &P,
55 PushType<SiteOperator<Symmetry_,complex<double>>,complex<double>>& pushlist, std::vector<std::vector<std::string>>& labellist,
56 const BC boundary=BC::OPEN);
57
58 static qarray<2> singlet (int N=0, int L=0) {return qarray<2>{0,N};};
59 static constexpr MODEL_FAMILY FAMILY = HUBBARD;
60 static constexpr int spinfac = 1;
61
62 static const map<string,any> defaults;
63 static const map<string,any> sweep_defaults;
64};
65
66// V is standard next-nearest neighbour density interaction
67// Vz and Vxy are anisotropic isospin-isospin next-nearest neighbour interaction
68const map<string,any> PeierlsHubbardU1xSU2::defaults =
69{
70 {"t",1.+0.i}, {"tPrime",0.i}, {"tRung",1.+0.i}, {"tPrimePrime",0.i},
71 {"mu",0.}, {"t0",0.},
72 {"U",0.}, {"Uph",0.},
73 {"V",0.}, {"Vrung",0.},
74 {"Jz",0.}, {"Jzrung",0.}, {"Jxy",0.}, {"Jxyrung",0.},
75 {"J",0.}, {"Jperp",0.},
76 {"Bz",0.}, {"Bx",0.},
77 {"X",0.}, {"Xrung",0.},
78 {"REMOVE_DOUBLE",false}, {"REMOVE_EMPTY",false}, {"REMOVE_UP",false}, {"REMOVE_DN",false}, {"mfactor",1}, {"k",0},
79 {"maxPower",2ul}, {"CYLINDER",false}, {"Ly",1ul}
80};
81
82const map<string,any> PeierlsHubbardU1xSU2::sweep_defaults =
83{
84 {"max_alpha",100.}, {"min_alpha",1.}, {"lim_alpha",11ul}, {"eps_svd",1e-7},
85 {"Dincr_abs", 4ul}, {"Dincr_per", 2ul}, {"Dincr_rel", 1.1},
86 {"min_Nsv",0ul}, {"max_Nrich",-1},
87 {"max_halfsweeps",24ul}, {"min_halfsweeps",6ul},
88 {"Minit",1ul}, {"Qinit",1ul}, {"Mlimit",500ul},
89 {"tol_eigval",1e-7}, {"tol_state",1e-6},
90 {"savePeriod",0ul}, {"CALC_S_ON_EXIT", true}, {"CONVTEST", DMRG::CONVTEST::VAR_2SITE}
91};
92
94PeierlsHubbardU1xSU2 (const size_t &L, const vector<Param> &params, const BC &boundary, const DMRG::VERBOSITY::OPTION &VERB)
95:Mpo<Symmetry,complex<double> > (L, qarray<Symmetry::Nq>({0,1}), "", PROP::HERMITIAN, PROP::NON_UNITARY, boundary, VERB),
98{
99 ParamHandler P(params,defaults);
100 size_t Lcell = P.size();
101
102 for (size_t l=0; l<N_sites; ++l)
103 {
104 N_phys += P.get<size_t>("Ly",l%Lcell);
105 setLocBasis(F[l].get_basis().qloc(),l);
106 }
107
108 param1d U = P.fill_array1d<double>("U", "Uorb", F[0].orbitals(), 0);
109 if (isfinite(U.a.sum()))
110 {
111 this->set_name("Hubbard");
112 }
113 else
114 {
115 this->set_name("U=∞-Hubbard");
116 }
117
118 PushType<SiteOperator<Symmetry,complex<double>>,complex<double>> pushlist;
119 std::vector<std::vector<std::string>> labellist;
120 PeierlsHubbardU1xSU2::set_operators(F, G, P, pushlist, labellist, boundary); // F, G are set in HubbardObservables
121
122 this->construct_from_pushlist(pushlist, labellist, Lcell);
123 this->finalize(PROP::COMPRESS, P.get<size_t>("maxPower"));
124
125 this->precalc_TwoSiteData();
126}
127
128template<typename Symmetry_>
130set_operators (const std::vector<FermionBase<Symmetry_> > &F, const vector<SUB_LATTICE> &G, const ParamHandler &P, PushType<SiteOperator<Symmetry_,complex<double>>,complex<double>>& pushlist, std::vector<std::vector<std::string>>& labellist, const BC boundary)
131{
132 std::size_t Lcell = P.size();
133 std::size_t N_sites = F.size();
134 if(labellist.size() != N_sites) {labellist.resize(N_sites);}
135
136 for (std::size_t loc=0; loc<N_sites; ++loc)
137 {
138 size_t lp1 = (loc+1)%N_sites;
139 size_t lp2 = (loc+2)%N_sites;
140 size_t lp3 = (loc+3)%N_sites;
141
142 std::size_t orbitals = F[loc].orbitals();
143 std::size_t next_orbitals = F[lp1].orbitals();
144 std::size_t nextn_orbitals = F[lp2].orbitals();
145 std::size_t nnextn_orbitals = F[lp3].orbitals();
146
147 stringstream ss;
148 ss << "Ly=" << P.get<size_t>("Ly",loc%Lcell);
149 labellist[loc].push_back(ss.str());
150
151 auto push_full = [&N_sites, &loc, &F, &P, &pushlist, &labellist, &boundary] (string xxxFull, string label,
152 const vector<SiteOperatorQ<Symmetry_,MatrixType>> &first,
153 const vector<vector<SiteOperatorQ<Symmetry_,MatrixType>>> &last,
154 vector<complex<double>> factor,
155 vector<bool> CONJ,
156 bool FERMIONIC) -> void
157 {
158 ArrayXXcd Full = P.get<Eigen::ArrayXXcd>(xxxFull);
159 vector<vector<std::pair<size_t,complex<double>> > > R = Geometry2D::rangeFormat(Full);
160
161 if (static_cast<bool>(boundary)) {assert(R.size() == N_sites and "Use an (N_sites)x(N_sites) hopping matrix for open BC!");}
162 else {assert(R.size() >= 2*N_sites and "Use at least a (2*N_sites)x(N_sites) hopping matrix for infinite BC!");}
163
164 for (size_t j=0; j<first.size(); j++)
165 for (size_t h=0; h<R[loc].size(); ++h)
166 {
167 size_t range = R[loc][h].first;
168 complex<double> value = R[loc][h].second;
169
170 if (range != 0)
171 {
172 vector<SiteOperatorQ<Symmetry_,MatrixType> > ops(range+1);
173 ops[0] = first[j];
174 for (size_t i=1; i<range; ++i)
175 {
176 if (FERMIONIC) {ops[i] = F[(loc+i)%N_sites].sign().template cast<complex<double>>();}
177 else {ops[i] = F[(loc+i)%N_sites].Id().template cast<complex<double>>();}
178 }
179 ops[range] = last[j][(loc+range)%N_sites];
180 complex<double> total_value = factor[j] * value;
181 if (CONJ[j]) total_value = conj(total_value);
182 pushlist.push_back(std::make_tuple(loc, ops, total_value));
183 }
184 }
185
186 stringstream ss;
187 ss << label << "(" << Geometry2D::hoppingInfo(Full) << ")";
188 labellist[loc].push_back(ss.str());
189 };
190
191 if (P.HAS("tFull"))
192 {
193 SiteOperatorQ<Symmetry_,MatrixType> cdagup_sign_local = (F[loc].cdag(UP,G[loc],0) * F[loc].sign()).template cast<complex<double>>();;
194 vector<SiteOperatorQ<Symmetry_,MatrixType> > cup_ranges(N_sites);
195 SiteOperatorQ<Symmetry_,MatrixType> cdagdn_sign_local = (F[loc].cdag(DN,G[loc],0) * F[loc].sign()).template cast<complex<double>>();;
196 vector<SiteOperatorQ<Symmetry_,MatrixType> > cdn_ranges(N_sites);
197 for (size_t i=0; i<N_sites; i++)
198 {
199 //auto Gi = static_cast<SUB_LATTICE>(static_cast<int>(pow(-1,i)));
200 cup_ranges[i] = F[i].c(UP,G[i],0).template cast<complex<double> >();
201 }
202 for (size_t i=0; i<N_sites; i++)
203 {
204 //auto Gi = static_cast<SUB_LATTICE>(static_cast<int>(pow(-1,i)));
205 cdn_ranges[i] = F[i].c(DN,G[i],0).template cast<complex<double> >();
206 }
207
208 vector<SiteOperatorQ<Symmetry_,MatrixType> > frst {cdagup_sign_local, cdagdn_sign_local};
209 vector<vector<SiteOperatorQ<Symmetry_,MatrixType> > > last {cup_ranges, cdn_ranges};
210 push_full("tFull", "tᵢⱼ", frst, last, {-std::sqrt(2.),-std::sqrt(2.)}, {false, false}, PROP::FERMIONIC);
211 }
212 if (P.HAS("Jfull"))
213 {
214 vector<SiteOperatorQ<Symmetry_,MatrixType> > first {F[loc].Sp(0).template cast<complex<double>>(),
215 F[loc].Sm(0).template cast<complex<double>>(),
216 F[loc].Sz(0).template cast<complex<double>>()};
217 vector<SiteOperatorQ<Symmetry_,MatrixType> > Sp_ranges(N_sites);
218 vector<SiteOperatorQ<Symmetry_,MatrixType> > Sm_ranges(N_sites);
219 vector<SiteOperatorQ<Symmetry_,MatrixType> > Sz_ranges(N_sites);
220 for (size_t i=0; i<N_sites; i++)
221 {
222 Sp_ranges[i] = F[i].Sp(0).template cast<complex<double>>();;
223 Sm_ranges[i] = F[i].Sm(0).template cast<complex<double>>();;
224 Sz_ranges[i] = F[i].Sz(0).template cast<complex<double>>();;
225 }
226
227 vector<vector<SiteOperatorQ<Symmetry_,MatrixType> > > last {Sm_ranges, Sp_ranges, Sz_ranges};
228 push_full("Jfull", "Jᵢⱼ", first, last, {0.5,0.5,1.}, {false, false, false}, PROP::BOSONIC);
229 }
230 // Local terms: U, t0, μ, t⟂, V⟂, J⟂
231
232 param1d Uph = P.fill_array1d<double>("Uph", "Uphorb", orbitals, loc%Lcell);
233 param1d V = P.fill_array1d<double>("V", "Vorb", orbitals, loc%Lcell);
234 //param1d t0 = P.fill_array1d<double>("t0", "t0orb", orbitals, loc%Lcell);
235 //param1d mu = P.fill_array1d<double>("mu", "muorb", orbitals, loc%Lcell);
236 param2d tPerp = P.fill_array2d<complex<double> >("tRung", "t", "tPerp", orbitals, loc%Lcell, P.get<bool>("CYLINDER"));
237 param2d Jxyperp = P.fill_array2d<double>("JxyRung", "Jxy", "JxyPerp", orbitals, loc%Lcell, P.get<bool>("CYLINDER"));
238 param2d Jzperp = P.fill_array2d<double>("JzRung", "Jz", "JzPerp", orbitals, loc%Lcell, P.get<bool>("CYLINDER"));
239 param2d Jperp = P.fill_array2d<double>("JRung", "J", "JPerp", orbitals, loc%Lcell, P.get<bool>("CYLINDER"));
240 param1d Bz = P.fill_array1d<double>("Bz", "Bzorb", orbitals, loc%Lcell);
241 param2d Vperp = P.fill_array2d<double>("Vrung", "V", "Vperp", orbitals, loc%Lcell, P.get<bool>("CYLINDER"));
242
243 labellist[loc].push_back(Uph.label);
244 //labellist[loc].push_back(t0.label);
245 //labellist[loc].push_back(mu.label);
246 labellist[loc].push_back(tPerp.label);
247 labellist[loc].push_back(Jxyperp.label);
248 labellist[loc].push_back(Jzperp.label);
249 labellist[loc].push_back(Jperp.label);
250 labellist[loc].push_back(Bz.label);
251 labellist[loc].push_back(Vperp.label);
252
254 (
255 F[loc].template HubbardHamiltonian<complex<double>,Symmetry_>(
256 Uph.a.cast<complex<double>>(),
257 tPerp.a.cast<complex<double>>(),
258 Vperp.a.cast<complex<double>>(),
259 Jzperp.a.cast<complex<double>>(),
260 Jxyperp.a.cast<complex<double>>(),
261 Bz.a.cast<complex<double>>())
262 );
263 pushlist.push_back(std::make_tuple(loc, Hloc, 1.+0.i));
264 }
265}
266
267} // end namespace VMPS::models
268
269#endif
@ DN
Definition: DmrgTypedefs.h:38
@ UP
Definition: DmrgTypedefs.h:37
MODEL_FAMILY
Definition: DmrgTypedefs.h:96
@ HUBBARD
Definition: DmrgTypedefs.h:96
BC
Definition: DmrgTypedefs.h:161
std::enable_if< Dummy::IS_SPIN_SU2() and!Dummy::IS_CHARGE_SU2(), Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::SU2< Sym::ChargeSU2 > >, complex< 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::SU2< Sym::ChargeSU2 > >, complex< double > > >::type Sz(size_t locx, size_t locy=0) const
Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::SU2< Sym::ChargeSU2 > >, complex< double > > Id() const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::SU2< Sym::ChargeSU2 > >, complex< double > > >::type Sm(size_t locx, size_t locy=0) const
vector< FermionBase< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::SU2< Sym::ChargeSU2 > > > > F
std::size_t N_phys
Definition: MpoTerms.h:400
std::size_t N_sites
Definition: MpoTerms.h:395
DMRG::VERBOSITY::OPTION VERB
Definition: MpoTerms.h:102
MpoTerms< Symmetry, OtherScalar > cast()
Definition: MpoTerms.h:3076
void calc(const std::size_t power)
Definition: MpoTerms.h:1135
std::string label
Definition: MpoTerms.h:615
Definition: Mpo.h:40
static std::vector< T > get_N_site_interaction(T const &Op0, Operator const &... Ops)
Definition: Mpo.h:117
Definition: SU2.h:36
static const map< string, any > defaults
PeierlsHubbardU1xSU2(Mpo< Symmetry, complex< double > > &Mpo_input, const vector< Param > &params)
static constexpr MODEL_FAMILY FAMILY
static constexpr int spinfac
static void set_operators(const std::vector< FermionBase< Symmetry_ > > &F, const vector< SUB_LATTICE > &G, const ParamHandler &P, PushType< SiteOperator< Symmetry_, complex< double > >, complex< double > > &pushlist, std::vector< std::vector< std::string > > &labellist, const BC boundary=BC::OPEN)
Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::SU2< Sym::ChargeSU2 > > Symmetry
static qarray< 2 > singlet(int N=0, int L=0)
Eigen::Matrix< complex< double >, Eigen::Dynamic, Eigen::Dynamic > MatrixType
static const map< string, any > sweep_defaults
#define MAKE_TYPEDEFS(MODEL)
Definition: macros.h:4
const bool COMPRESS
Definition: DmrgTypedefs.h:499
const bool NON_UNITARY
Definition: DmrgTypedefs.h:495
const bool FERMIONIC
Definition: DmrgTypedefs.h:496
const bool HERMITIAN
Definition: DmrgTypedefs.h:492
const bool BOSONIC
Definition: DmrgTypedefs.h:498
void finalize(bool PRINT_STATS=false)
Definition: functions.h:127
Definition: qarray.h:26