VMPS++
Loading...
Searching...
No Matches
KondoU1xSU2.h
Go to the documentation of this file.
1#ifndef KONDOMODEL_SU2XSU2_H_
2#define KONDOMODEL_SU2XSU2_H_
3
4#include "symmetry/S1xS2.h"
5#include "symmetry/U1.h"
6#include "symmetry/SU2.h"
7#include "bases/SpinBase.h"
8#include "bases/FermionBase.h"
9#include "Mpo.h"
10#include "ParamReturner.h"
11#include "Geometry2D.h" // from TOOLS
13
14namespace VMPS
15{
16
17class KondoU1xSU2 : public Mpo<Sym::S1xS2<Sym::U1<Sym::SpinU1>,Sym::SU2<Sym::ChargeSU2> > ,double>,
18 public KondoObservables<Sym::S1xS2<Sym::U1<Sym::SpinU1>,Sym::SU2<Sym::ChargeSU2> > >,
19 public ParamReturner
20{
21public:
24 typedef Eigen::Matrix<double,Eigen::Dynamic,Eigen::Dynamic> MatrixType;
27
28private:
29 typedef Eigen::Index Index;
31
32public:
33
36 KondoU1xSU2 (const size_t &L, const vector<Param> &params, const BC &boundary=BC::OPEN, const DMRG::VERBOSITY::OPTION &VERB=DMRG::VERBOSITY::OPTION::ON_EXIT);
38
39 static qarray<2> singlet (int N=0, int L=0)
40 {
41 assert(N%2==0);
42 int T = abs(0.5*(N-L));
43 return qarray<2>{0,2*T+1};
44 };
45
46 template<typename Symmetry_>
47 static void set_operators (const std::vector<SpinBase<Symmetry_> > &B, const std::vector<FermionBase<Symmetry_> > &F, const vector<SUB_LATTICE> &G, const ParamHandler &P,
48 PushType<SiteOperator<Symmetry_,double>,double>& pushlist, std::vector<std::vector<std::string>>& labellist,
49 const BC boundary=BC::OPEN);
50
51 static const std::map<string,std::any> defaults;
52 static const map<string,any> sweep_defaults;
53};
54
55const std::map<string,std::any> KondoU1xSU2::defaults =
56{
57 {"t",1.}, {"tRung",0.}, {"tPrime",0.}, {"tPrimePrime",0.},
58 {"J",1.}, {"Jz",0.}, {"U",0.},
59 {"V",0.}, {"Vrung",0.},
60 {"Bz",0.}, {"Bzsub",0.}, {"Kz",0.},
61 {"Inext",0.}, {"Iprev",0.}, {"I3next",0.}, {"I3prev",0.}, {"I3loc",0.},
62 {"D",2ul}, {"maxPower",1ul}, {"CYLINDER",false}, {"Ly",1ul}, {"LyF",1ul},
63 {"REMOVE_DOUBLE",false}, {"REMOVE_EMPTY",false}, {"REMOVE_UP",false}, {"REMOVE_DN",false}, {"mfactor",1}, {"k",1},
64};
65
66const map<string,any> KondoU1xSU2::sweep_defaults =
67{
68 {"max_alpha",100.}, {"min_alpha",1.}, {"lim_alpha",16ul}, {"eps_svd",1e-7},
69 {"Dincr_abs",5ul}, {"Dincr_per",2ul}, {"Dincr_rel",1.1},
70 {"min_Nsv",0ul}, {"max_Nrich",-1},
71 {"max_halfsweeps",30ul}, {"min_halfsweeps",10ul},
72 {"Dinit",5ul}, {"Qinit",6ul}, {"Dlimit",200ul},
73 {"tol_eigval",1e-6}, {"tol_state",1e-5},
74 {"savePeriod",0ul}, {"CALC_S_ON_EXIT", true}, {"CONVTEST",DMRG::CONVTEST::VAR_2SITE}
75};
76
78KondoU1xSU2 (const size_t &L, const vector<Param> &params, const BC &boundary, const DMRG::VERBOSITY::OPTION &VERB)
79:Mpo<Symmetry> (L, qarray<Symmetry::Nq>({0,1}), "", PROP::HERMITIAN, PROP::NON_UNITARY, boundary, VERB),
82{
83 ParamHandler P(params,defaults);
84 size_t Lcell = P.size();
85
86 for (size_t l=0; l<N_sites; ++l)
87 {
88 N_phys += P.get<size_t>("LyF",l%Lcell);
89 setLocBasis((B[l].get_basis().combine(F[l].get_basis())).qloc(),l);
90 }
91
92 this->set_name("Kondo");
93
95 std::vector<std::vector<std::string>> labellist;
96 set_operators(B, F, G, P, pushlist, labellist, boundary);
97
98 this->construct_from_pushlist(pushlist, labellist, Lcell);
99 this->finalize(PROP::COMPRESS, P.get<size_t>("maxPower"));
100
101 this->precalc_TwoSiteData();
102}
103
104template<typename Symmetry_>
106set_operators (const std::vector<SpinBase<Symmetry_> > &B, const std::vector<FermionBase<Symmetry_> > &F, const vector<SUB_LATTICE> &G, const ParamHandler &P,
107 PushType<SiteOperator<Symmetry_,double>,double>& pushlist, std::vector<std::vector<std::string>>& labellist, const BC boundary)
108{
109 std::size_t Lcell = P.size();
110 std::size_t N_sites = B.size();
111 if(labellist.size() != N_sites) {labellist.resize(N_sites);}
112
113 for (std::size_t loc=0; loc<N_sites; ++loc)
114 {
115 size_t lp1 = (loc+1)%N_sites;
116 size_t lp2 = (loc+2)%N_sites;
117
118/* auto Gloc = static_cast<SUB_LATTICE>(static_cast<int>(pow(-1,loc)));*/
119/* auto Glp1 = static_cast<SUB_LATTICE>(static_cast<int>(pow(-1,lp1)));*/
120/* auto Glp2 = static_cast<SUB_LATTICE>(static_cast<int>(pow(-1,lp2)));*/
121
122 std::size_t Forbitals = F[loc].orbitals();
123 std::size_t Fnext_orbitals = F[lp1].orbitals();
124 std::size_t Fnextn_orbitals = F[lp2].orbitals();
125
126 std::size_t Borbitals = B[loc].orbitals();
127 std::size_t Bnext_orbitals = B[lp1].orbitals();
128 std::size_t Bnextn_orbitals = B[lp2].orbitals();
129
130 stringstream Slabel;
131 Slabel << "S=" << print_frac_nice(frac(B[loc].get_D()-1,2));
132 labellist[loc].push_back(Slabel.str());
133
134 auto push_full = [&N_sites, &loc, &B, &F, &P, &pushlist, &labellist, &boundary] (string xxxFull, string label,
135 const vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > &first,
136 const vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > &last,
137 vector<double> factor, bool FERMIONIC) -> void
138 {
139 ArrayXXd Full = P.get<Eigen::ArrayXXd>(xxxFull);
140 vector<vector<std::pair<size_t,double> > > R = Geometry2D::rangeFormat(Full);
141
142 if (static_cast<bool>(boundary)) {assert(R.size() == N_sites and "Use an (N_sites)x(N_sites) hopping matrix for open BC!");}
143 else {assert(R.size() >= 2*N_sites and "Use at least a (2*N_sites)x(N_sites) hopping matrix for infinite BC!");}
144
145 for (size_t j=0; j<first.size(); j++)
146 for (size_t h=0; h<R[loc].size(); ++h)
147 {
148 size_t range = R[loc][h].first;
149 double value = R[loc][h].second;
150
151 if (range != 0)
152 {
153 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > ops(range+1);
154 ops[0] = first[j];
155 for (size_t i=1; i<range; ++i)
156 {
157 if (FERMIONIC) {ops[i] = kroneckerProduct(B[(loc+i)%N_sites].Id(), F[(loc+i)%N_sites].sign());}
158 else {ops[i] = kroneckerProduct(B[(loc+i)%N_sites].Id(), F[(loc+i)%N_sites].Id());}
159 }
160 ops[range] = last[j][(loc+range)%N_sites];
161 pushlist.push_back(std::make_tuple(loc, ops, factor[j] * value));
162 }
163 }
164
165 stringstream ss;
166 ss << label << "(" << Geometry2D::hoppingInfo(Full) << ")";
167 labellist[loc].push_back(ss.str());
168 };
169
170 if (P.HAS("tFull"))
171 {
172 SiteOperatorQ<Symmetry_,Eigen::MatrixXd> cdagUP_sign_local = kroneckerProduct(B[loc].Id(),(F[loc].cdag(UP,G[loc],0) * F[loc].sign()));
173 SiteOperatorQ<Symmetry_,Eigen::MatrixXd> cdagDN_sign_local = kroneckerProduct(B[loc].Id(),(F[loc].cdag(DN,G[loc],0) * F[loc].sign()));
174 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > cUP_ranges(N_sites);
175 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > cDN_ranges(N_sites);
176 for (size_t i=0; i<N_sites; i++)
177 {
178 //auto Gi = static_cast<SUB_LATTICE>(static_cast<int>(pow(-1,i)));
179 cUP_ranges[i] = kroneckerProduct(B[loc].Id(),F[i].c(UP,G[i],0));
180 }
181 for (size_t i=0; i<N_sites; i++)
182 {
183 //auto Gi = static_cast<SUB_LATTICE>(static_cast<int>(pow(-1,i)));
184 cDN_ranges[i] = kroneckerProduct(B[loc].Id(),F[i].c(DN,G[i],0));
185 }
186
187 vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > first {cdagUP_sign_local, cdagDN_sign_local};
188 vector<vector<SiteOperatorQ<Symmetry_,Eigen::MatrixXd> > > last {cUP_ranges, cDN_ranges};
189 push_full("tFull", "tᵢⱼ", first, last, {-std::sqrt(2.), -std::sqrt(2.)}, PROP::FERMIONIC);
190 }
191
192 if (!P.HAS("tFull"))
193 {
194 param2d tPara = P.fill_array2d<double>("t", "tPara", {Forbitals, Fnext_orbitals}, loc%Lcell);
195 labellist[loc].push_back(tPara.label);
196
197 if (loc < N_sites-1 or !static_cast<bool>(boundary))
198 {
199 for (int alfa=0; alfa<Forbitals; ++alfa)
200 for (int beta=0; beta<Fnext_orbitals; ++beta)
201 {
202 auto PsiDagUp_loc = kroneckerProduct(B[loc].Id(), F[loc].cdag(UP,G[loc],alfa));
203 auto PsiDagDn_loc = kroneckerProduct(B[loc].Id(), F[loc].cdag(DN,G[loc],alfa));
204 auto Sign_loc = kroneckerProduct(B[loc].Id(), F[loc].sign());
205 auto PsiUp_lp1 = kroneckerProduct(B[lp1].Id(), F[lp1].c(UP,G[lp1],beta));
206 auto PsiDn_lp1 = kroneckerProduct(B[lp1].Id(), F[lp1].c(DN,G[lp1],beta));
207
208 auto Otmp_loc = PsiDagUp_loc * Sign_loc;
209 pushlist.push_back(std::make_tuple(loc, Mpo<Symmetry_,double>::get_N_site_interaction(Otmp_loc, PsiUp_lp1), -tPara(alfa,beta) * sqrt(2.)) );
210
211 //c†DNcDN
212 Otmp_loc = PsiDagDn_loc * Sign_loc;
213 pushlist.push_back(std::make_tuple(loc, Mpo<Symmetry_,double>::get_N_site_interaction(Otmp_loc, PsiDn_lp1), -tPara(alfa,beta) * sqrt(2.)) );
214 }
215 }
216 }
217
218 // local terms
219
220 // Kondo-J
221 param1d J = P.fill_array1d<double>("J", "Jorb", Forbitals, loc%Lcell);
222 labellist[loc].push_back(J.label);
223
224 // Kondo-Jz
225 param1d Jz = P.fill_array1d<double>("Jz", "Jzorb", Forbitals, loc%Lcell);
226 labellist[loc].push_back(Jz.label);
227
228 // t⟂
229 param2d tPerp = P.fill_array2d<double>("tRung", "t", "tPerp", Forbitals, loc%Lcell, P.get<bool>("CYLINDER"));
230 labellist[loc].push_back(tPerp.label);
231
232 // Hubbard-U
233 param1d U = P.fill_array1d<double>("U", "Uorb", Forbitals, loc%Lcell);
234 labellist[loc].push_back(U.label);
235
236 // Bz substrate
237 param1d Bzsub = P.fill_array1d<double>("Bzsub", "Bzsuborb", Forbitals, loc%Lcell);
238 labellist[loc].push_back(Bzsub.label);
239
240 // Bz impurities
241 param1d Bz = P.fill_array1d<double>("Bz", "Bzorb", Borbitals, loc%Lcell);
242 labellist[loc].push_back(Bz.label);
243
244 // Kz anisotropy
245 param1d Kz = P.fill_array1d<double>("Kz","Kzorb", Borbitals, loc%Lcell);
246 labellist[loc].push_back(Kz.label);
247
248 ArrayXXd muPerp = B[loc].ZeroHopping();
249 ArrayXXd nuPerp = B[loc].ZeroHopping();
250 ArrayXXd Jxyperp = B[loc].ZeroHopping();
251 ArrayXXd Jzperp = B[loc].ZeroHopping();
252
253 //set Heisenberg part of Kondo Hamiltonian
254 auto KondoHamiltonian = kroneckerProduct(B[loc].HeisenbergHamiltonian(Jxyperp,Jzperp,Bz.a,muPerp,nuPerp,Kz.a), F[loc].Id());
255
256 ArrayXXd Vperp = F[loc].ZeroHopping();
257 ArrayXXd Jxysubperp = F[loc].ZeroHopping();
258 ArrayXXd Jzsubperp = F[loc].ZeroHopping();
259
260 //set Hubbard part of Kondo Hamiltonian
261 KondoHamiltonian += kroneckerProduct(B[loc].Id(), F[loc].HubbardHamiltonian(U.a,tPerp.a,Vperp,Jzsubperp,Jxysubperp,Bzsub.a));
262
263 //set Kondo part of Hamiltonian
264 for (int alfa=0; alfa<Forbitals; ++alfa)
265 {
266 if (J(alfa) != 0.)
267 {
268 assert(Borbitals == Forbitals and "Can only do a Kondo ladder with the same amount of spins and fermionic orbitals in y-direction!");
269 KondoHamiltonian += 0.5*J(alfa) * kroneckerProduct(B[loc].Scomp(SP,alfa), F[loc].Sm(alfa));
270 KondoHamiltonian += 0.5*J(alfa) * kroneckerProduct(B[loc].Scomp(SM,alfa), F[loc].Sp(alfa));
271 KondoHamiltonian += J(alfa) * kroneckerProduct(B[loc].Scomp(SZ,alfa), F[loc].Sz(alfa));
272 }
273 if (Jz(alfa) != 0.)
274 {
275 KondoHamiltonian += Jz(alfa) * kroneckerProduct(B[loc].Scomp(SZ,alfa), F[loc].Sz(alfa));
276 }
277 }
278 pushlist.push_back(std::make_tuple(loc, Mpo<Symmetry_,double>::get_N_site_interaction(KondoHamiltonian), 1.));
279 }
280}
281
282} //end namespace VMPS
283
284#endif
boost::rational< int > frac
Definition: DmrgExternal.h:11
std::string print_frac_nice(frac r)
Definition: DmrgExternal.h:32
@ DN
Definition: DmrgTypedefs.h:38
@ UP
Definition: DmrgTypedefs.h:37
MODEL_FAMILY
Definition: DmrgTypedefs.h:96
@ KONDO
Definition: DmrgTypedefs.h:96
@ SZ
Definition: DmrgTypedefs.h:60
@ SP
Definition: DmrgTypedefs.h:60
@ SM
Definition: DmrgTypedefs.h:60
BC
Definition: DmrgTypedefs.h:161
@ B
Definition: DmrgTypedefs.h:130
SiteOperator< Symmetry, Scalar_ > kroneckerProduct(const SiteOperator< Symmetry, Scalar_ > &O1, const SiteOperator< Symmetry, Scalar_ > &O2)
Definition: SiteOperator.h:164
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::SU2< Sym::ChargeSU2 > > > >::type cdag(size_t locx, size_t locy=0, double factor=std::sqrt(2.)) const
std::enable_if< Dummy::IS_SPIN_SU2(), Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::SU2< Sym::ChargeSU2 > > > >::type c(size_t locx, size_t locy=0, double factor=1.) const
vector< SpinBase< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::SU2< Sym::ChargeSU2 > > > > B
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::SU2< Sym::ChargeSU2 > > > >::type Sz(size_t locx, size_t locy=0) const
vector< FermionBase< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::SU2< Sym::ChargeSU2 > > > > F
std::enable_if< Dummy::IS_CHARGE_SU2(), Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::SU2< Sym::ChargeSU2 > > > >::type T(size_t locx, size_t locy=0, double factor=1.) const
std::enable_if<!Dummy::IS_SPIN_SU2(), Mpo< Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::SU2< Sym::ChargeSU2 > > > >::type Scomp(SPINOP_LABEL Sa, size_t locx, size_t locy=0, double factor=1.) const
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
Definition: SU2.h:36
static const std::map< string, std::any > defaults
Definition: KondoU1xSU2.h:51
static void set_operators(const std::vector< SpinBase< Symmetry_ > > &B, const std::vector< FermionBase< Symmetry_ > > &F, const vector< SUB_LATTICE > &G, const ParamHandler &P, PushType< SiteOperator< Symmetry_, double >, double > &pushlist, std::vector< std::vector< std::string > > &labellist, const BC boundary=BC::OPEN)
Definition: KondoU1xSU2.h:106
static qarray< 2 > singlet(int N=0, int L=0)
Definition: KondoU1xSU2.h:39
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixType
Definition: KondoU1xSU2.h:24
SiteOperatorQ< Symmetry, MatrixType > OperatorType
Definition: KondoU1xSU2.h:23
static constexpr MODEL_FAMILY FAMILY
Definition: KondoU1xSU2.h:26
Eigen::Index Index
Definition: KondoU1xSU2.h:29
static const map< string, any > sweep_defaults
Definition: KondoU1xSU2.h:52
Sym::S1xS2< Sym::U1< Sym::SpinU1 >, Sym::SU2< Sym::ChargeSU2 > > Symmetry
Definition: KondoU1xSU2.h:22
#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
Definition: qarray.h:26