VMPS++
Loading...
Searching...
No Matches
HeisenbergSU2.h
Go to the documentation of this file.
1#ifndef STRAWBERRY_HEISENBERGSU2
2#define STRAWBERRY_HEISENBERGSU2
3
4#include "symmetry/SU2.h"
6#include "bases/SpinBase.h"
7#include "Mpo.h"
8#include "ParamReturner.h"
9#include "Geometry2D.h" // from TOOLS
10
11namespace VMPS
12{
13
29class HeisenbergSU2 : public Mpo<Sym::SU2<Sym::SpinSU2>,double>, public HeisenbergObservables<Sym::SU2<Sym::SpinSU2> >, public ParamReturner
30{
31public:
34 typedef Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> MatrixType;
36
37 static qarray<1> singlet(int N=0) {return qarray<1>{1};};
38 static constexpr MODEL_FAMILY FAMILY = HEISENBERG;
39
40private:
41
42 typedef Eigen::Index Index;
44 typedef Eigen::SparseMatrix<double> SparseMatrixType;
45
46public:
47
48 //---constructors---
49
51
53
59 HeisenbergSU2 (const size_t &L, const vector<Param> &params={}, const BC & boundary=BC::OPEN, const DMRG::VERBOSITY::OPTION& VERB=DMRG::VERBOSITY::ON_EXIT);
60
61 HeisenbergSU2 (Mpo<Symmetry> &Mpo_input, const vector<Param> &params)
62 :Mpo<Symmetry>(Mpo_input),
65 {
66 ParamHandler P(params,HeisenbergSU2::defaults);
67 size_t Lcell = P.size();
68 N_phys = 0;
69 for (size_t l=0; l<N_sites; ++l) N_phys += P.get<size_t>("Ly",l%Lcell);
70 this->precalc_TwoSiteData();
71 this->HERMITIAN = true;
72 this->HAMILTONIAN = true;
73 };
75
85 static void set_operators (const std::vector<SpinBase<Symmetry> > &B, const ParamHandler &P,
86 PushType<SiteOperator<Symmetry,double>,double>& pushlist, std::vector<std::vector<std::string>>& labellist, const BC boundary=BC::OPEN);
87
88
91 bool validate (qarray<1> qnum) const;
92
93 static const std::map<string,std::any> defaults;
94 static const std::map<string,std::any> sweep_defaults;
95};
96
97const std::map<string,std::any> HeisenbergSU2::defaults =
98{
99 {"J",1.}, {"Jprime",0.}, {"Jprimeprime",0.}, {"Jrung",1.},
100 {"R",0.}, {"Offset",0.},
101 {"D",2ul}, {"maxPower",2ul}, {"CYLINDER",false}, {"Ly",1ul}, {"mfactor",1}
102};
103
104const std::map<string,std::any> HeisenbergSU2::sweep_defaults =
105{
106 {"max_alpha",100.}, {"min_alpha",1.e-11}, {"lim_alpha",10ul}, {"eps_svd",1.e-7},
107 {"Mincr_abs", 50ul}, {"Mincr_per", 2ul}, {"Mincr_rel", 1.1},
108 {"min_Nsv",0ul}, {"max_Nrich",-1},
109 {"max_halfsweeps",50ul}, {"min_halfsweeps",20ul},
110 {"Minit",1ul}, {"Qinit",1ul}, {"Mlimit",1000ul},
111 {"tol_eigval",1e-7}, {"tol_state",1e-6},
112 {"savePeriod",0ul}, {"CALC_S_ON_EXIT", true}, {"CONVTEST", DMRG::CONVTEST::VAR_HSQ}
113};
114
116HeisenbergSU2 (const size_t &L, const vector<Param> &params, const BC & boundary, const DMRG::VERBOSITY::OPTION &VERB)
117:Mpo<Symmetry> (L, qarray<Symmetry::Nq>({1}), "", PROP::HERMITIAN, PROP::NON_UNITARY, boundary, VERB),
120{
121 ParamHandler P(params,defaults);
122 size_t Lcell = P.size();
123
124 for (size_t l=0; l<N_sites; ++l)
125 {
126 N_phys += P.get<size_t>("Ly",l%Lcell);
127 setLocBasis(B[l].get_basis().qloc(),l);
128 }
129
130 this->set_name("Heisenberg");
131 this->set_verbosity(VERB);
132
134 std::vector<std::vector<std::string>> labellist;
135 set_operators(B, P, pushlist, labellist, boundary);
136
137 this->construct_from_pushlist(pushlist, labellist, Lcell);
138 this->finalize(PROP::COMPRESS, P.get<size_t>("maxPower"));
139
140 this->precalc_TwoSiteData();
141}
142
144validate (qarray<1> qnum) const
145{
146 frac Smax(0,1);
147 frac q_in(qnum[0]-1,2);
148 for (size_t l=0; l<N_sites; ++l) { Smax+=frac(B[l].get_D()-1,2); }
149 if (Smax.denominator()==q_in.denominator() and q_in <= Smax) {return true;}
150 else {return false;}
151}
152
154set_operators (const vector<SpinBase<Symmetry> > &B, const ParamHandler &P, PushType<SiteOperator<Symmetry,double>,double>& pushlist, std::vector<std::vector<std::string>>& labellist, const BC boundary)
155{
156 std::size_t Lcell = P.size();
157 std::size_t N_sites = B.size();
158 if(labellist.size() != N_sites) {labellist.resize(N_sites);}
159
160 for (std::size_t loc=0; loc<N_sites; ++loc)
161 {
162 size_t lp1 = (loc+1)%N_sites;
163 size_t lp2 = (loc+2)%N_sites;
164 size_t lp3 = (loc+3)%N_sites;
165
166 std::size_t orbitals = B[loc].orbitals();
167 std::size_t next1_orbitals = B[lp1].orbitals();
168 std::size_t next2_orbitals = B[lp2].orbitals();
169 std::size_t next3_orbitals = B[lp3].orbitals();
170
171 stringstream ss1, ss2;
172 ss1 << "S=" << print_frac_nice(frac(P.get<size_t>("D",loc%Lcell)-1,2));
173 ss2 << "Ly=" << P.get<size_t>("Ly",loc%Lcell);
174 labellist[loc].push_back(ss1.str());
175 labellist[loc].push_back(ss2.str());
176
177 auto push_full = [&N_sites, &loc, &B, &P, &pushlist, &labellist, &boundary] (string xxxFull, string label,
178 const vector<SiteOperatorQ<Symmetry,Eigen::MatrixXd> > &first,
179 const vector<vector<SiteOperatorQ<Symmetry,Eigen::MatrixXd> > > &last,
180 vector<double> factor) -> void
181 {
182 ArrayXXd Full = P.get<Eigen::ArrayXXd>(xxxFull);
183 vector<vector<std::pair<size_t,double> > > R = Geometry2D::rangeFormat(Full);
184
185 if (static_cast<bool>(boundary)) {assert(R.size() == N_sites and "Use an (N_sites)x(N_sites) hopping matrix for open BC!");}
186 else {assert(R.size() >= 2*N_sites and "Use at least a (2*N_sites)x(N_sites) hopping matrix for infinite BC!");}
187
188 for (size_t j=0; j<first.size(); j++)
189 for (size_t h=0; h<R[loc].size(); ++h)
190 {
191 size_t range = R[loc][h].first;
192 double value = R[loc][h].second;
193
194 if (range != 0)
195 {
196 vector<SiteOperatorQ<Symmetry,Eigen::MatrixXd> > ops(range+1);
197 ops[0] = first[j];
198 for (size_t i=1; i<range; ++i)
199 {
200 ops[i] = B[(loc+i)%N_sites].Id();
201 }
202 ops[range] = last[j][(loc+range)%N_sites];
203 pushlist.push_back(std::make_tuple(loc, ops, factor[j] * value));
204 }
205 }
206
207 stringstream ss;
208 ss << label << "(" << Geometry2D::hoppingInfo(Full) << ")";
209 labellist[loc].push_back(ss.str());
210 };
211
212 // Local Terms: J⟂
213 param2d Jperp = P.fill_array2d<double>("Jrung", "J", "Jperp", orbitals, loc%Lcell, P.get<bool>("CYLINDER"));
214 labellist[loc].push_back(Jperp.label);
215
216 param1d Offset = P.fill_array1d<double>("Offset", "Offsetorb", orbitals, loc%Lcell);
217 labellist[loc].push_back(Offset.label);
218
219 auto Hloc = Mpo<Symmetry,double>::get_N_site_interaction(B[loc].HeisenbergHamiltonian(Jperp.a,Offset.a));
220 pushlist.push_back(std::make_tuple(loc, Hloc, 1.));
221
222 // Case where a full coupling matrix is providedf: Jᵢⱼ (all the code below this funtion will be skipped then.)
223 if (P.HAS("Jfull"))
224 {
225 vector<SiteOperatorQ<Symmetry,Eigen::MatrixXd> > first {B[loc].Sdag(0)};
226 vector<SiteOperatorQ<Symmetry,Eigen::MatrixXd> > S_ranges(N_sites); for (size_t i=0; i<N_sites; i++) {S_ranges[i] = B[i].S(0);}
227 vector<vector<SiteOperatorQ<Symmetry,Eigen::MatrixXd> > > last {S_ranges};
228 push_full("Jfull", "Jᵢⱼ", first, last, {std::sqrt(3.)});
229 }
230 if (P.HAS("JfullA"))
231 {
232 vector<SiteOperatorQ<Symmetry,Eigen::MatrixXd> > first {B[loc].Sdag(1)};
233 vector<SiteOperatorQ<Symmetry,Eigen::MatrixXd> > S_ranges(N_sites); for (size_t i=0; i<N_sites; i++) {S_ranges[i] = B[i].S(1);}
234 vector<vector<SiteOperatorQ<Symmetry,Eigen::MatrixXd> > > last {S_ranges};
235 push_full("JfullA", "JAᵢⱼ", first, last, {std::sqrt(3.)});
236 }
237
238 // Case where a full coupling matrix is providedf: Jᵢⱼ (all the code below this funtion will be skipped then.)
239 if (P.HAS("Rfull"))
240 {
241 vector<SiteOperatorQ<Symmetry,Eigen::MatrixXd> > first {B[loc].Qdag(0)};
242 vector<SiteOperatorQ<Symmetry,Eigen::MatrixXd> > Q_ranges(N_sites); for (size_t i=0; i<N_sites; i++) {Q_ranges[i] = B[i].Q(0);}
243 vector<vector<SiteOperatorQ<Symmetry,Eigen::MatrixXd> > > last {Q_ranges};
244 push_full("Rfull", "Rᵢⱼ", first, last, {std::sqrt(5.)});
245 }
246
247 if (!P.HAS("Jfull"))
248 {
249 // Nearest-neighbour terms: J
250 param2d Jpara = P.fill_array2d<double>("J", "Jpara", {orbitals, next1_orbitals}, loc%Lcell);
251 param2d Rpara = P.fill_array2d<double>("R", "Rpara", {orbitals, next1_orbitals}, loc%Lcell);
252 labellist[loc].push_back(Jpara.label);
253 labellist[loc].push_back(Rpara.label);
254
255 if (loc < N_sites-1 or !static_cast<bool>(boundary))
256 {
257 for(std::size_t alfa=0; alfa<orbitals; ++alfa)
258 for(std::size_t beta=0; beta<next1_orbitals; ++beta)
259 {
260 auto opsQ = Mpo<Symmetry,double>::get_N_site_interaction(B[loc].Qdag(alfa), B[lp1].Q(beta));
261 auto opsJ = Mpo<Symmetry,double>::get_N_site_interaction(B[loc].Sdag(alfa), B[lp1].S(beta));
262 pushlist.push_back(std::make_tuple(loc,opsJ,std::sqrt(3.)*Jpara(alfa,beta)));
263 pushlist.push_back(std::make_tuple(loc,opsQ,std::sqrt(5.)*Rpara(alfa,beta)));
264 }
265 }
266
267 // Next-nearest-neighbour terms: J'
268 param2d Jprime = P.fill_array2d<double>("Jprime", "Jprime_array", {orbitals, next2_orbitals}, loc%Lcell);
269 labellist[loc].push_back(Jprime.label);
270
271 if (loc < N_sites-2 or !static_cast<bool>(boundary))
272 {
273 for (std::size_t alfa=0; alfa<orbitals; ++alfa)
274 for (std::size_t beta=0; beta<next2_orbitals; ++beta)
275 {
276 auto ops = Mpo<Symmetry,double>::get_N_site_interaction(B[loc].Sdag(alfa), B[lp1].Id(), B[lp2].S(beta));
277 pushlist.push_back(std::make_tuple(loc,ops,std::sqrt(3.)*Jprime(alfa,beta)));
278 }
279 }
280
281 // 3rd-neighbour terms: J''
282 param2d Jprimeprime = P.fill_array2d<double>("Jprimeprime", "Jprimeprime_array", {orbitals, next3_orbitals}, loc%Lcell);
283 labellist[loc].push_back(Jprimeprime.label);
284
285 if (loc < N_sites-3 or !static_cast<bool>(boundary))
286 {
287
288 for(std::size_t alfa=0; alfa<orbitals; ++alfa)
289 for(std::size_t beta=0; beta<next3_orbitals; ++beta)
290 {
291 auto ops = Mpo<Symmetry,double>::get_N_site_interaction(B[loc].Sdag(alfa), B[lp1].Id(), B[lp2].Id(), B[lp3].S(beta));
292 pushlist.push_back(std::make_tuple(loc,ops,std::sqrt(3.)*Jprimeprime(alfa,beta)));
293 }
294 }
295 }
296 }
297}
298
299} //end namespace VMPS
300
301#endif
boost::rational< int > frac
Definition: DmrgExternal.h:11
std::string print_frac_nice(frac r)
Definition: DmrgExternal.h:32
MODEL_FAMILY
Definition: DmrgTypedefs.h:96
@ HEISENBERG
Definition: DmrgTypedefs.h:96
BC
Definition: DmrgTypedefs.h:161
@ B
Definition: DmrgTypedefs.h:130
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Sym::SU2< Sym::SpinSU2 >, double > >::type Q(size_t locx, size_t locy=0, double factor=1.) const
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Sym::SU2< Sym::SpinSU2 >, double > >::type Qdag(size_t locx, size_t locy=0, double factor=std::sqrt(5.)) const
vector< SpinBase< Sym::SU2< Sym::SpinSU2 > > > B
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Sym::SU2< Sym::SpinSU2 >, double > >::type Sdag(size_t locx, size_t locy=0, double factor=std::sqrt(3.)) const
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Sym::SU2< Sym::SpinSU2 >, double > >::type S(size_t locx, size_t locy=0, double factor=1.) const
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
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
void precalc_TwoSiteData(bool FORCE=false)
Definition: SU2.h:36
Heisenberg Model.
Definition: HeisenbergSU2.h:30
Eigen::SparseMatrix< double > SparseMatrixType
Definition: HeisenbergSU2.h:44
static void set_operators(const std::vector< SpinBase< Symmetry > > &B, const ParamHandler &P, PushType< SiteOperator< Symmetry, double >, double > &pushlist, std::vector< std::vector< std::string > > &labellist, const BC boundary=BC::OPEN)
static qarray< 1 > singlet(int N=0)
Definition: HeisenbergSU2.h:37
static constexpr MODEL_FAMILY FAMILY
Definition: HeisenbergSU2.h:38
bool validate(qarray< 1 > qnum) const
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixType
Definition: HeisenbergSU2.h:34
Eigen::Index Index
Definition: HeisenbergSU2.h:42
static const std::map< string, std::any > defaults
Definition: HeisenbergSU2.h:93
HeisenbergSU2(Mpo< Symmetry > &Mpo_input, const vector< Param > &params)
Definition: HeisenbergSU2.h:61
Sym::SU2< Sym::SpinSU2 > Symmetry
Definition: HeisenbergSU2.h:32
static const std::map< string, std::any > sweep_defaults
Definition: HeisenbergSU2.h:94
Symmetry::qType qType
Definition: HeisenbergSU2.h:43
#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 HERMITIAN
Definition: DmrgTypedefs.h:492
Definition: qarray.h:26