VMPS++
Loading...
Searching...
No Matches
SpinlessFermionsU1.h
Go to the documentation of this file.
1#ifndef STRAWBERRY_SPINLESSFERMIONSU1
2#define STRAWBERRY_SPINLESSFERMIONSU1
3
4#include "symmetry/U1.h"
5#include "models/SpinlessFermionsObservables.h"
6#include "ParamReturner.h"
7#include "Geometry2D.h" // from TOOLS
8
9namespace VMPS
10{
11class SpinlessFermionsU1 : public Mpo<Sym::U1<Sym::ChargeU1>,double>,
12 public SpinlessFermionsObservables<Sym::U1<Sym::ChargeU1> >,
13 public ParamReturner
14{
15public:
16
19
20public:
21
24
25 SpinlessFermionsU1(Mpo<Symmetry> &Mpo_input, const vector<Param> &params)
26 :Mpo<Symmetry>(Mpo_input),
29 {
30 ParamHandler P(params,SpinlessFermionsU1::defaults);
31 size_t Lcell = P.size();
32 N_phys = 0;
33 for (size_t l=0; l<N_sites; ++l) N_phys += P.get<size_t>("Ly",l%Lcell);
34 this->precalc_TwoSiteData();
35 };
36
37 SpinlessFermionsU1 (const size_t &L, const vector<Param> &params, const BC &boundary=BC::OPEN, const DMRG::VERBOSITY::OPTION &VERB=DMRG::VERBOSITY::OPTION::ON_EXIT);
39
40 template<typename Symmetry_>
41 static void set_operators (const std::vector<SpinlessFermionBase<Symmetry_> > &F, const ParamHandler &P,
42 PushType<SiteOperator<Symmetry_,double>,double>& pushlist, std::vector<std::vector<std::string>>& labellist, const BC boundary=BC::OPEN);
43
44 static qarray<1> singlet (int N) {return qarray<1>{N};};
45 static constexpr MODEL_FAMILY FAMILY = SPINLESS;
46 static constexpr int spinfac = 1;
47
48 static const std::map<string,std::any> defaults;
49// static const std::map<string,std::any> sweep_defaults;
50};
51
52const std::map<string,std::any> SpinlessFermionsU1::defaults =
53{
54 {"t",1.}, {"tPrime",0.},
55 {"V",0.}, {"Vph",0.},
56 {"Vprime",0.}, {"VphPrime",0.},
57 {"mu",0.},{"t0",0.},
58 {"D",2ul}, {"CALC_SQUARE",true}, {"CYLINDER",false}, {"OPEN_BC",true}, {"Ly",1ul},
59};
60
61//const std::map<string,std::any> SpinlessFermionsU1::sweep_defaults =
62//{
63// {"max_alpha",100.}, {"min_alpha",1.e-11}, {"lim_alpha",10ul}, {"eps_svd",1.e-7},
64// {"Dincr_abs", 4ul}, {"Dincr_per", 2ul}, {"Dincr_rel", 1.1},
65// {"min_Nsv",0ul}, {"max_Nrich",-1},
66// {"max_halfsweeps",20ul}, {"min_halfsweeps",1ul},
67// {"Dinit",4ul}, {"Qinit",5ul}, {"Dlimit",100ul},
68// {"tol_eigval",1e-7}, {"tol_state",1e-6},
69// {"savePeriod",0ul}, {"CALC_S_ON_EXIT", true}, {"CONVTEST", DMRG::CONVTEST::VAR_2SITE}
70//};
71
73SpinlessFermionsU1 (const size_t &L, const vector<Param> &params, const BC &boundary, const DMRG::VERBOSITY::OPTION &VERB)
74:Mpo<Symmetry> (L, Symmetry::qvacuum(), "", PROP::HERMITIAN, PROP::NON_UNITARY, boundary, VERB),
75 SpinlessFermionsObservables<Sym::U1<Sym::ChargeU1> >(L,params,SpinlessFermionsU1::defaults),
76 ParamReturner() //SpinlessFermionsU1::sweep_defaults
77{
78 ParamHandler P(params,SpinlessFermionsU1::defaults);
79 size_t Lcell = P.size();
80
81 for (size_t l=0; l<N_sites; ++l)
82 {
83 N_phys += P.get<size_t>("Ly",l%Lcell);
84 setLocBasis(F[l].get_basis().qloc(),l);
85 }
86
87 //HamiltonianTermsXd<Symmetry> Terms(N_sites, P.get<bool>("OPEN_BC"));
88 //F.resize(N_sites);
89
90 this->set_name("SpinlessFermions");
91
93 std::vector<std::vector<std::string>> labellist;
94 set_operators(F, P, pushlist, labellist, boundary);
95
96 //set_operators(F,P,Terms);
97 //this->construct_from_Terms(Terms, Lcell, P.get<bool>("CALC_SQUARE"), P.get<bool>("OPEN_BC"));
98 //this->precalc_TwoSiteData();
99
100 this->construct_from_pushlist(pushlist, labellist, Lcell);
101 this->finalize(PROP::COMPRESS, P.get<size_t>("maxPower"));
102 this->precalc_TwoSiteData();
103}
104
105template<typename Symmetry_>
107set_operators (const std::vector<SpinlessFermionBase<Symmetry_> > &F, const ParamHandler &P,
108 PushType<SiteOperator<Symmetry_,double>,double>& pushlist, std::vector<std::vector<std::string>>& labellist, const BC boundary)
109{
110 std::size_t Lcell = P.size();
111 std::size_t N_sites = F.size();
112 if(labellist.size() != N_sites) {labellist.resize(N_sites);}
113
114 for (std::size_t loc=0; loc<N_sites; ++loc)
115 {
116 size_t lp1 = (loc+1)%N_sites;
117 size_t lp2 = (loc+2)%N_sites;
118
119 std::size_t orbitals = F[loc].orbitals();
120 std::size_t next_orbitals = F[lp1].orbitals();
121 std::size_t nextn_orbitals = F[lp2].orbitals();
122
123 stringstream ss;
124 ss << "Ly=" << P.get<size_t>("Ly",loc%Lcell);
125 labellist[loc].push_back(ss.str());
126
127 auto push_full = [&N_sites, &loc, &F, &P, &pushlist, &labellist, &boundary] (string xxxFull, string label,
128 const vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > &first,
129 const vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > &last,
130 vector<double> factor, bool FERMIONIC) -> void
131 {
132 ArrayXXd Full = P.get<Eigen::ArrayXXd>(xxxFull);
133 vector<vector<std::pair<size_t,double> > > R = Geometry2D::rangeFormat(Full);
134
135 if (static_cast<bool>(boundary)) {assert(R.size() == N_sites and "Use an (N_sites)x(N_sites) hopping matrix for open BC!");}
136 else {assert(R.size() >= 2*N_sites and "Use at least a (2*N_sites)x(N_sites) hopping matrix for infinite BC!");}
137
138 for (size_t j=0; j<first.size(); j++)
139 for (size_t h=0; h<R[loc].size(); ++h)
140 {
141 size_t range = R[loc][h].first;
142 double value = R[loc][h].second;
143
144 if (range != 0)
145 {
146 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > ops(range+1);
147 ops[0] = first[j];
148 for (size_t i=1; i<range; ++i)
149 {
150 if (FERMIONIC) {ops[i] = F[(loc+i)%N_sites].sign();}
151 else {ops[i] = F[(loc+i)%N_sites].Id();}
152 }
153 ops[range] = last[j][(loc+range)%N_sites];
154 pushlist.push_back(std::make_tuple(loc, ops, factor[j] * value));
155 }
156 }
157
158 stringstream ss;
159 ss << label << "(" << Geometry2D::hoppingInfo(Full) << ")";
160 labellist[loc].push_back(ss.str());
161 };
162
163 if (P.HAS("tFull"))
164 {
165// ArrayXXd Full = P.get<Eigen::ArrayXXd>("tFull");
166// vector<vector<std::pair<size_t,double> > > R = Geometry2D::rangeFormat(Full);
167//
168// if (P.get<bool>("OPEN_BC")) {assert(R.size() == N_sites and "Use an (N_sites)x(N_sites) hopping matrix for open BC!");}
169// else {assert(R.size() >= 2*N_sites and "Use at least a (2*N_sites)x(N_sites) hopping matrix for infinite BC!");}
170//
171// for (size_t h=0; h<R[loc].size(); ++h)
172// {
173// size_t range = R[loc][h].first;
174// double value = R[loc][h].second;
175//
176// size_t Ntrans = (range == 0)? 0:range-1;
177// vector<SiteOperator<Symmetry_,double> > TransOps(Ntrans);
178// for (size_t i=0; i<Ntrans; ++i)
179// {
180// TransOps[i] = F[(loc+i+1)%N_sites].sign();
181// }
182//
183// if (range != 0)
184// {
185// auto c_sign_local = F[loc].c(0) * F[loc].sign();
186// auto cdag_sign_local = F[loc].cdag(0) * F[loc].sign();
187// auto c_range = F[(loc+range)%N_sites].c(0);
188// auto cdag_range = F[(loc+range)%N_sites].cdag(0);
189//
190// //hopping
191// Terms.push(range, loc, -value, cdag_sign_local, TransOps, c_range);
192// Terms.push(range, loc, +value, c_sign_local, TransOps, cdag_range);
193// }
194// }
195//
196// stringstream ss;
197// ss << "tᵢⱼ(" << Geometry2D::hoppingInfo(Full) << ")";
198// Terms.save_label(loc,ss.str());
199
200 SiteOperatorQ<Symmetry_,Eigen::MatrixXd> c_sign_local = F[loc].c(0) * F[loc].sign();
201 SiteOperatorQ<Symmetry_,Eigen::MatrixXd> cdag_sign_local = F[loc].cdag(0) * F[loc].sign();
202
203 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);}
204 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);}
205
206 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > frst {cdag_sign_local, c_sign_local};
207 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {c_ranges, cdag_ranges};
208
209 push_full("tFull", "tᵢⱼ", frst, last, {-1., +1.}, PROP::FERMIONIC);
210 }
211
212 if (P.HAS("VextFull"))
213 {
214// ArrayXXd Full = P.get<Eigen::ArrayXXd>("Vfull");
215// vector<vector<std::pair<size_t,double> > > R = Geometry2D::rangeFormat(Full);
216//
217// if (P.get<bool>("OPEN_BC")) {assert(R.size() == N_sites and "Use an (N_sites)x(N_sites) hopping matrix for open BC!");}
218// else {assert(R.size() >= 2*N_sites and "Use at least a (2*N_sites)x(N_sites) hopping matrix for infinite BC!");}
219//
220// for (size_t h=0; h<R[loc].size(); ++h)
221// {
222// size_t range = R[loc][h].first;
223// double value = R[loc][h].second;
224//
225// size_t Ntrans = (range == 0)? 0:range-1;
226// vector<SiteOperator<Symmetry_,double> > TransOps(Ntrans);
227// for (size_t i=0; i<Ntrans; ++i)
228// {
229// TransOps[i] = F[(loc+i+1)%N_sites].Id();
230// }
231//
232// if (range != 0)
233// {
234// auto n_loc = F[loc].n(0);
235// auto n_hop = F[(loc+range)%N_sites].n(0);
236//
237// Terms.push(range, loc, value, n_loc, TransOps, n_hop);
238// }
239// }
240//
241// stringstream ss;
242// ss << "Vᵢⱼ(" << Geometry2D::hoppingInfo(Full) << ")";
243// Terms.save_label(loc,ss.str());
244
245 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {F[loc].n(0)};
246 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > n_ranges(N_sites);
247 for (size_t i=0; i<N_sites; i++)
248 {
249 n_ranges[i] = F[i].n(0);
250 }
251
252 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {n_ranges};
253 push_full("VextFull", "Vᵢⱼ", first, last, {1.}, PROP::BOSONIC);
254 }
255
256 if (P.HAS("VphFull"))
257 {
258 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {F[loc].nph(0)};
259 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > nph_ranges(N_sites);
260 for (size_t i=0; i<N_sites; i++)
261 {
262 nph_ranges[i] = F[i].nph(0);
263 }
264
265 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {nph_ranges};
266 push_full("VphFull", "Vphᵢⱼ", first, last, {1.}, PROP::BOSONIC);
267 }
268
269 // Local terms: t0, mu
270
271 param1d t0 = P.fill_array1d<double>("t0", "t0orb", orbitals, loc%Lcell);
272 param1d mu = P.fill_array1d<double>("mu", "muorb", orbitals, loc%Lcell);
273
274 labellist[loc].push_back(t0.label);
275 labellist[loc].push_back(mu.label);
276
277 // Nearest-neighbour terms: t, V, Vph
278
279// if (!P.HAS("tFull") and !P.HAS("Vfull") and !P.HAS("VphFull"))
280// {
281// param2d tPara = P.fill_array2d<double>("t", "tPara", {orbitals, next_orbitals}, loc%Lcell);
282// param2d Vpara = P.fill_array2d<double>("V", "Vpara", {orbitals, next_orbitals}, loc%Lcell);
283// param2d VphPara = P.fill_array2d<double>("Vph", "VphPara", {orbitals, next_orbitals}, loc%Lcell);
284//
285// Terms.save_label(loc, tPara.label);
286// Terms.save_label(loc, Vpara.label);
287// Terms.save_label(loc, VphPara.label);
288//
289// if (loc < N_sites-1 or !P.get<bool>("OPEN_BC"))
290// {
291// for (std::size_t alfa=0; alfa<orbitals; ++alfa)
292// for (std::size_t beta=0; beta<next_orbitals; ++beta)
293// {
294// Terms.push_tight(loc, -tPara(alfa,beta), F[loc].cdag(alfa)*F[loc].sign(), F[lp1].c(beta));
295// Terms.push_tight(loc, +tPara(alfa,beta), F[loc].c(alfa) *F[loc].sign(), F[lp1].cdag(beta));
296//
297// Terms.push_tight(loc, Vpara(alfa,beta), F[loc].n(alfa), F[lp1].n(beta));
298// Terms.push_tight(loc, VphPara(alfa,beta), F[loc].n(alfa)-0.5*F[loc].Id(), F[lp1].n(beta)-0.5*F[lp1].Id());
299// }
300// }
301//
302// // Next-nearest-neighbour terms: tPrime, Vprime, VphPrime
303//
304// param2d tPrime = P.fill_array2d<double>("tPrime", "tPrime_array", {orbitals, nextn_orbitals}, loc%Lcell);
305// param2d Vprime = P.fill_array2d<double>("Vprime", "Vprime_array", {orbitals, nextn_orbitals}, loc%Lcell);
306// param2d VphPrime = P.fill_array2d<double>("VphPrime", "VphPrime_array", {orbitals, nextn_orbitals}, loc%Lcell);
307//
308// Terms.save_label(loc, tPrime.label);
309// Terms.save_label(loc, Vprime.label);
310// Terms.save_label(loc, VphPrime.label);
311//
312// if (loc < N_sites-2 or !P.get<bool>("OPEN_BC"))
313// {
314// for (std::size_t alfa=0; alfa<orbitals; ++alfa)
315// for (std::size_t beta=0; beta<nextn_orbitals; ++beta)
316// {
317// Terms.push_nextn(loc, -tPrime(alfa,beta), F[loc].cdag(alfa)*F[loc].sign(), F[lp1].sign(), F[lp2].c(beta));
318// Terms.push_nextn(loc, -tPrime(alfa,beta), -1.*F[loc].c(alfa)*F[loc].sign(), F[lp1].sign(), F[lp2].cdag(beta));
319//
320// Terms.push_nextn(loc, Vprime(alfa,beta), F[loc].n(alfa), F[lp1].Id(), F[lp2].n(beta));
321// Terms.push_nextn(loc, VphPrime(alfa,beta), F[loc].n(alfa)-0.5*F[loc].Id(), F[lp1].Id(), F[lp2].n(beta)-0.5*F[lp2].Id());
322// }
323// }
324// }
325 }
326}
327
328} //end namespace VMPS
329
330#endif
MODEL_FAMILY
Definition: DmrgTypedefs.h:96
@ SPINLESS
Definition: DmrgTypedefs.h:96
BC
Definition: DmrgTypedefs.h:161
std::size_t N_phys
Definition: MpoTerms.h:400
void finalize(const bool COMPRESS=true, const std::size_t power=1, const double tolerance=::mynumeric_limits< double >::epsilon())
Definition: MpoTerms.h:1281
std::size_t N_sites
Definition: MpoTerms.h:395
void setLocBasis(const std::vector< std::vector< qType > > &q)
Definition: MpoTerms.h:715
DMRG::VERBOSITY::OPTION VERB
Definition: MpoTerms.h:102
void set_name(const std::string &label_in)
Definition: MpoTerms.h:471
std::string label
Definition: MpoTerms.h:615
Definition: Mpo.h:40
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)
vector< SpinlessFermionBase< Sym::U1< Sym::ChargeU1 > > > F
Definition: U1.h:25
static qarray< 1 > singlet(int N)
Sym::U1< Sym::ChargeU1 > Symmetry
static void set_operators(const std::vector< SpinlessFermionBase< 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
static const std::map< string, std::any > defaults
SpinlessFermionsU1(Mpo< Symmetry > &Mpo_input, const vector< Param > &params)
static constexpr int spinfac
#define MAKE_TYPEDEFS(MODEL)
Definition: macros.h:4
const bool COMPRESS
Definition: DmrgTypedefs.h:499
const bool FERMIONIC
Definition: DmrgTypedefs.h:496
const bool BOSONIC
Definition: DmrgTypedefs.h:498
Definition: qarray.h:26