1#ifndef STRAWBERRY_HEISENBERGU1
2#define STRAWBERRY_HEISENBERGU1
14#include "Geometry2D.h"
65 size_t Lcell = P.size();
67 for (
size_t l=0; l<
N_sites; ++l)
N_phys += P.get<
size_t>(
"Ly",l%Lcell);
87 template<
typename Symmetry_>
96 static const std::map<string,std::any>
defaults;
102 {
"J",0.}, {
"Jprime",0.}, {
"Jrung",0.},
103 {
"Jxy",0.}, {
"Jxyprime",0.}, {
"Jxyrung",0.},
104 {
"Jz",0.}, {
"Jzprime",0.}, {
"Jzrung",0.},
106 {
"Dy",0.}, {
"Dyprime",0.}, {
"Dyrung",0.},
107 {
"Bz",0.}, {
"Kz",0.},
108 {
"mu",0.}, {
"nu",0.},
109 {
"D",2ul}, {
"maxPower",2ul}, {
"CYLINDER",
false}, {
"Ly",1ul}, {
"mfactor",1}
114 {
"max_alpha",100.}, {
"min_alpha",1.e-11}, {
"lim_alpha",10ul}, {
"eps_svd",1.e-7},
115 {
"Mincr_abs", 50ul}, {
"Mincr_per", 2ul}, {
"Mincr_rel", 1.1},
116 {
"min_Nsv",0ul}, {
"max_Nrich",-1},
117 {
"max_halfsweeps",20ul}, {
"min_halfsweeps",4ul},
118 {
"Minit",1ul}, {
"Qinit",1ul}, {
"Mlimit",1000ul},
119 {
"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(
B[l].get_basis().qloc(),l);
145 if (P.HAS_ANY_OF({
"Jxy",
"Jxypara",
"Jxyperp",
"Jxyfull"}))
147 this->set_name(
"XXZ");
149 else if (P.HAS_ANY_OF({
"Jz",
"Jzpara",
"Jzperp",
"Jzfull"}))
151 this->set_name(
"Ising");
155 this->set_name(
"Heisenberg");
159 std::vector<std::vector<std::string>> labellist;
160 set_operators(
B, P, pushlist, labellist, boundary);
162 this->construct_from_pushlist(pushlist, labellist, Lcell);
165 this->precalc_TwoSiteData();
172 frac q_in(qnum[0],2);
173 for (
size_t l=0; l<
N_sites; ++l) { Smax+=
frac(
B[l].get_D()-1,2); }
174 if (Smax.denominator()==q_in.denominator() and q_in <= Smax) {
return true;}
178template<
typename Symmetry_>
182 std::size_t Lcell = P.size();
187 for (std::size_t loc=0; loc<
N_sites; ++loc)
192 std::size_t orbitals =
B[loc].orbitals();
193 std::size_t next_orbitals =
B[lp1].orbitals();
194 std::size_t nextn_orbitals =
B[lp2].orbitals();
196 stringstream ss1, ss2;
198 ss2 <<
"Ly=" << P.get<
size_t>(
"Ly",loc%Lcell);
199 labellist[loc].push_back(ss1.str());
200 labellist[loc].push_back(ss2.str());
202 auto push_full = [&
N_sites, &loc, &
B, &P, &pushlist, &labellist, &boundary]
203 (
string xxxFull,
string label,
204 const vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > &first,
205 const vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > &last,
206 vector<double> factor) ->
void
208 ArrayXXd Full = P.get<Eigen::ArrayXXd>(xxxFull);
209 vector<vector<std::pair<size_t,double> > > R = Geometry2D::rangeFormat(Full);
211 if (
static_cast<bool>(boundary)) {assert(R.size() ==
N_sites and
"Use an (N_sites)x(N_sites) hopping matrix for open BC!");}
212 else {assert(R.size() >= 2*
N_sites and
"Use at least a (2*N_sites)x(N_sites) hopping matrix for infinite BC!");}
214 for (
size_t j=0; j<first.size(); j++)
215 for (
size_t h=0; h<R[loc].size(); ++h)
217 size_t range = R[loc][h].first;
218 double value = R[loc][h].second;
222 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > ops(range+1);
224 for (
size_t i=1; i<range; ++i)
228 ops[range] = last[j][(loc+range)%
N_sites];
229 pushlist.push_back(std::make_tuple(loc, ops, factor[j] * value));
234 ss <<
label <<
"(" << Geometry2D::hoppingInfo(Full) <<
")";
235 labellist[loc].push_back(ss.str());
240 param1d Bz = P.fill_array1d<
double>(
"Bz",
"Bzorb", orbitals, loc%Lcell);
241 param1d Kz = P.fill_array1d<
double>(
"Kz",
"Kzorb", orbitals, loc%Lcell);
242 param2d Jperp = P.fill_array2d<
double>(
"Jrung",
"J",
"Jperp", orbitals, loc%Lcell, P.get<
bool>(
"CYLINDER"));
243 param2d Jxyperp = P.fill_array2d<
double>(
"Jxyrung",
"Jxy",
"Jxyperp", orbitals, loc%Lcell, P.get<
bool>(
"CYLINDER"));
244 param2d Jzperp = P.fill_array2d<
double>(
"Jzrung",
"Jz",
"Jzperp", orbitals, loc%Lcell, P.get<
bool>(
"CYLINDER"));
245 param1d mu = P.fill_array1d<
double>(
"mu",
"muorb", orbitals, loc%Lcell);
246 param1d nu = P.fill_array1d<
double>(
"nu",
"nuorb", orbitals, loc%Lcell);
248 labellist[loc].push_back(Bz.label);
249 labellist[loc].push_back(Kz.label);
250 labellist[loc].push_back(Jperp.label);
251 labellist[loc].push_back(Jxyperp.label);
252 labellist[loc].push_back(Jzperp.label);
253 labellist[loc].push_back(mu.label);
254 labellist[loc].push_back(nu.label);
256 Eigen::ArrayXd Bx_array =
B[loc].ZeroField();
257 Eigen::ArrayXd Kx_array =
B[loc].ZeroField();
258 Eigen::ArrayXXd Dyperp_array =
B[loc].ZeroHopping();
260 auto sum_array = [] (
const ArrayXXd& a1,
const ArrayXXd& a2)
262 ArrayXXd res(a1.rows(), a1.cols());
263 for (
int i=0; i<a1.rows(); ++i)
264 for (
int j=0; j<a1.rows(); ++j)
266 res(i,j) = a1(i,j) + a2(i,j);
272 B[loc].HeisenbergHamiltonian(sum_array(Jperp.a,Jxyperp.a), sum_array(Jperp.a,Jzperp.a), Bz.a, mu.a, nu.a, Kz.a));
273 pushlist.push_back(std::make_tuple(loc, Hloc, 1.));
278 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {
B[loc].Sp(0),
B[loc].Sm(0),
B[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++) {Sp_ranges[i] =
B[i].Sp(0); Sm_ranges[i] =
B[i].Sm(0); Sz_ranges[i] =
B[i].Sz(0);}
284 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {Sm_ranges, Sp_ranges, Sz_ranges};
285 push_full(
"Jfull",
"Jᵢⱼ", first, last, {0.5,0.5,1.0});
287 if (P.HAS(
"Jxyfull"))
289 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {
B[loc].Sp(0),
B[loc].Sm(0)};
290 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Sp_ranges(
N_sites);
291 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Sm_ranges(
N_sites);
292 for (
size_t i=0; i<
N_sites; i++) {Sp_ranges[i] =
B[i].Sp(0); Sm_ranges[i] =
B[i].Sm(0);}
294 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {Sm_ranges, Sp_ranges};
295 push_full(
"Jxyfull",
"Jxyᵢⱼ", first, last, {0.5,0.5});
299 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {
B[loc].Sz(0)};
300 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Sz_ranges(
N_sites);
301 for (
size_t i=0; i<
N_sites; i++) {Sz_ranges[i] =
B[i].Sz(0);}
303 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {Sz_ranges};
304 push_full(
"Jzfull",
"Jzᵢⱼ", first, last, {1.0});
306 if (P.HAS(
"JxyfullA"))
308 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {
B[loc].Sp(1),
B[loc].Sm(1)};
309 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Sp_ranges(
N_sites);
310 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Sm_ranges(
N_sites);
311 for (
size_t i=0; i<
N_sites; i++) {Sp_ranges[i] =
B[i].Sp(1);
312 Sm_ranges[i] =
B[i].Sm(1);}
314 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {Sm_ranges, Sp_ranges};
315 push_full(
"JxyfullA",
"JxyAᵢⱼ", first, last, {0.5,0.5});
317 if (P.HAS(
"JzfullA"))
319 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {
B[loc].Sz(1)};
320 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Sz_ranges(
N_sites);
321 for (
size_t i=0; i<
N_sites; i++) {Sz_ranges[i] =
B[i].Sz(1);}
323 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {Sz_ranges};
324 push_full(
"JzfullA",
"JzAᵢⱼ", first, last, {1.0});
328 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {
B[loc].Qp(0),
B[loc].Qm(0),
B[loc].Qz(0),
B[loc].Qpz(0),
B[loc].Qmz(0)};
329 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Qp_ranges(
N_sites);
330 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Qm_ranges(
N_sites);
331 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Qz_ranges(
N_sites);
332 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Qpz_ranges(
N_sites);
333 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > Qmz_ranges(
N_sites);
334 for (
size_t i=0; i<
N_sites; i++)
336 Qp_ranges[i] =
B[i].Qp(0);
337 Qm_ranges[i] =
B[i].Qm(0);
338 Qz_ranges[i] =
B[i].Qz(0);
339 Qpz_ranges[i] =
B[i].Qpz(0);
340 Qmz_ranges[i] =
B[i].Qmz(0);
343 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {Qm_ranges, Qp_ranges, Qz_ranges, Qmz_ranges, Qpz_ranges};
344 push_full(
"Rfull",
"Rᵢⱼ", first, last, {0.5, 0.5, 1.0, 0.5, 0.5});
347 if (P.HAS(
"Jfull") or P.HAS(
"Jxyfull") or P.HAS(
"Jzfull") or P.HAS(
"Rfull"))
continue;
350 param2d Jxypara = P.fill_array2d<
double>(
"Jxy",
"Jxypara", {orbitals, next_orbitals}, loc%Lcell);
351 param2d Jzpara = P.fill_array2d<
double>(
"Jz",
"Jzpara", {orbitals, next_orbitals}, loc%Lcell);
352 param2d Jpara = P.fill_array2d<
double>(
"J",
"Jpara", {orbitals, next_orbitals}, loc%Lcell);
353 labellist[loc].push_back(Jxypara.label);
354 labellist[loc].push_back(Jzpara.label);
355 labellist[loc].push_back(Jpara.label);
357 if (loc <
N_sites-1 or !
static_cast<bool>(boundary))
359 for (std::size_t alfa=0; alfa < orbitals; ++alfa)
360 for (std::size_t beta=0; beta < next_orbitals; ++beta)
363 B[lp1].Scomp(
SM,beta)),
364 0.5*Jxypara(alfa,beta)+0.5*Jpara(alfa,beta)));
367 0.5*Jxypara(alfa,beta)+0.5*Jpara(alfa,beta)));
370 Jzpara(alfa,beta)+Jpara(alfa,beta)));
375 param2d Rpara = P.fill_array2d<
double>(
"R",
"Rpara", {orbitals, next_orbitals}, loc%Lcell);
376 labellist[loc].push_back(Rpara.label);
378 if (loc <
N_sites-1 or !
static_cast<bool>(boundary))
380 for (std::size_t alfa=0; alfa < orbitals; ++alfa)
381 for (std::size_t beta=0; beta < next_orbitals; ++beta)
385 0.5*Rpara(alfa,beta)));
388 0.5*Rpara(alfa,beta)));
391 0.5*Rpara(alfa,beta)));
394 0.5*Rpara(alfa,beta)));
402 param2d Jxyprime = P.fill_array2d<
double>(
"Jxyprime",
"Jxyprime_array", {orbitals, nextn_orbitals}, loc%Lcell);
403 param2d Jzprime = P.fill_array2d<
double>(
"Jzprime",
"Jzprime_array", {orbitals, nextn_orbitals}, loc%Lcell);
404 param2d Jprime = P.fill_array2d<
double>(
"Jprime",
"Jprime_array", {orbitals, nextn_orbitals}, loc%Lcell);
405 labellist[loc].push_back(Jxyprime.label);
406 labellist[loc].push_back(Jzprime.label);
407 labellist[loc].push_back(Jprime.label);
409 if (loc <
N_sites-2 or !
static_cast<bool>(boundary))
411 for (std::size_t alfa=0; alfa < orbitals; ++alfa)
412 for (std::size_t beta=0; beta < nextn_orbitals; ++beta)
416 B[lp2].Scomp(
SM,beta)),
417 0.5*Jxyprime(alfa,beta)+0.5*Jprime(alfa,beta)));
421 0.5*Jxyprime(alfa,beta)+0.5*Jprime(alfa,beta)));
425 Jzprime(alfa,beta)+Jprime(alfa,beta)));
boost::rational< int > frac
std::string print_frac_nice(frac r)
vector< SpinBase< Sym::U1< Sym::SpinU1 > > > B
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Sym::U1< Sym::SpinU1 >, double > >::type Scomp(SPINOP_LABEL Sa, size_t locx, size_t locy=0, double factor=1.) 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)
SiteOperator< Symmetry, SparseMatrix< double > > OperatorType
HeisenbergU1(Mpo< Symmetry > &Mpo_input, const vector< Param > ¶ms)
bool validate(qarray< 1 > qnum) const
static qarray< 1 > singlet(int N=0)
static const std::map< string, std::any > sweep_defaults
Sym::U1< Sym::SpinU1 > Symmetry
static constexpr MODEL_FAMILY FAMILY
static const std::map< string, std::any > defaults
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)
#define MAKE_TYPEDEFS(MODEL)
void finalize(bool PRINT_STATS=false)