1#ifndef STRAWBERRY_HEISENBERGSU2
2#define STRAWBERRY_HEISENBERGSU2
34 typedef Eigen::Matrix<
double,Eigen::Dynamic,Eigen::Dynamic>
MatrixType;
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);
93 static const std::map<string,std::any>
defaults;
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}
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},
121 ParamHandler P(params,defaults);
122 size_t Lcell = P.size();
124 for (
size_t l=0; l<N_sites; ++l)
126 N_phys += P.get<
size_t>(
"Ly",l%Lcell);
127 setLocBasis(
B[l].get_basis().qloc(),l);
130 this->set_name(
"Heisenberg");
131 this->set_verbosity(VERB);
134 std::vector<std::vector<std::string>> labellist;
135 set_operators(
B, P, pushlist, labellist, boundary);
137 this->construct_from_pushlist(pushlist, labellist, Lcell);
140 this->precalc_TwoSiteData();
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;}
156 std::size_t Lcell = P.size();
160 for (std::size_t loc=0; loc<
N_sites; ++loc)
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();
171 stringstream ss1, ss2;
173 ss2 <<
"Ly=" << P.get<
size_t>(
"Ly",loc%Lcell);
174 labellist[loc].push_back(ss1.str());
175 labellist[loc].push_back(ss2.str());
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
182 ArrayXXd Full = P.get<Eigen::ArrayXXd>(xxxFull);
183 vector<vector<std::pair<size_t,double> > > R = Geometry2D::rangeFormat(Full);
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!");}
188 for (
size_t j=0; j<first.size(); j++)
189 for (
size_t h=0; h<R[loc].size(); ++h)
191 size_t range = R[loc][h].first;
192 double value = R[loc][h].second;
196 vector<SiteOperatorQ<Symmetry,Eigen::MatrixXd> > ops(range+1);
198 for (
size_t i=1; i<range; ++i)
202 ops[range] = last[j][(loc+range)%
N_sites];
203 pushlist.push_back(std::make_tuple(loc, ops, factor[j] * value));
208 ss <<
label <<
"(" << Geometry2D::hoppingInfo(Full) <<
")";
209 labellist[loc].push_back(ss.str());
213 param2d Jperp = P.fill_array2d<
double>(
"Jrung",
"J",
"Jperp", orbitals, loc%Lcell, P.get<
bool>(
"CYLINDER"));
214 labellist[loc].push_back(Jperp.label);
216 param1d Offset = P.fill_array1d<
double>(
"Offset",
"Offsetorb", orbitals, loc%Lcell);
217 labellist[loc].push_back(Offset.label);
220 pushlist.push_back(std::make_tuple(loc, Hloc, 1.));
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.)});
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.)});
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.)});
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);
255 if (loc <
N_sites-1 or !
static_cast<bool>(boundary))
257 for(std::size_t alfa=0; alfa<orbitals; ++alfa)
258 for(std::size_t beta=0; beta<next1_orbitals; ++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)));
268 param2d Jprime = P.fill_array2d<
double>(
"Jprime",
"Jprime_array", {orbitals, next2_orbitals}, loc%Lcell);
269 labellist[loc].push_back(Jprime.label);
271 if (loc <
N_sites-2 or !
static_cast<bool>(boundary))
273 for (std::size_t alfa=0; alfa<orbitals; ++alfa)
274 for (std::size_t beta=0; beta<next2_orbitals; ++beta)
277 pushlist.push_back(std::make_tuple(loc,ops,std::sqrt(3.)*Jprime(alfa,beta)));
282 param2d Jprimeprime = P.fill_array2d<
double>(
"Jprimeprime",
"Jprimeprime_array", {orbitals, next3_orbitals}, loc%Lcell);
283 labellist[loc].push_back(Jprimeprime.label);
285 if (loc <
N_sites-3 or !
static_cast<bool>(boundary))
288 for(std::size_t alfa=0; alfa<orbitals; ++alfa)
289 for(std::size_t beta=0; beta<next3_orbitals; ++beta)
292 pushlist.push_back(std::make_tuple(loc,ops,std::sqrt(3.)*Jprimeprime(alfa,beta)));
boost::rational< int > frac
std::string print_frac_nice(frac r)
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
DMRG::VERBOSITY::OPTION VERB
static std::vector< T > get_N_site_interaction(T const &Op0, Operator const &... Ops)
void precalc_TwoSiteData(bool FORCE=false)
Eigen::SparseMatrix< double > SparseMatrixType
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)
static constexpr MODEL_FAMILY FAMILY
bool validate(qarray< 1 > qnum) const
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixType
static const std::map< string, std::any > defaults
HeisenbergSU2(Mpo< Symmetry > &Mpo_input, const vector< Param > ¶ms)
Sym::SU2< Sym::SpinSU2 > Symmetry
static const std::map< string, std::any > sweep_defaults
#define MAKE_TYPEDEFS(MODEL)