VMPS++
Loading...
Searching...
No Matches
SpinSite.h
Go to the documentation of this file.
1#ifndef SPINSITE_H_
2#define SPINSITE_H_
3
4#include "symmetry/U0.h"
5#include "symmetry/U1.h"
6#include "symmetry/SU2.h"
7#include "symmetry/S1xS2.h"
8
9#include "DmrgTypedefs.h"
10#include "sites/SpinSiteXxSU2.h"
11#include "sites/SpinSiteSU2.h"
12#include "sites/SpinSiteSU2xX.h"
13
14template <typename Symmetry_, size_t order=0ul>
16{
17 typedef double Scalar;
18 typedef Symmetry_ Symmetry;
21
22public:
23
25 SpinSite(std::size_t D_input, int mfactor_input=1);
26 // mfactor: 1 for physical sites, 0 for ancilla sites for thermodynamics
27
28 OperatorType Id_1s() const {return Id_1s_;}
29 OperatorType Zero_1s() const {return Zero_1s_;}
30 OperatorType F_1s() const {return F_1s_;}
31
32 OperatorType n_1s() const {return n_1s(UP) + n_1s(DN);}
33
34 // dipole
35 OperatorType Sz_1s() const {return Sz_1s_;}
36 OperatorType Sp_1s() const {return Sp_1s_;}
37 OperatorType Sm_1s() const {return Sm_1s_;}
38
39 // quadrupole
40 OperatorType Qz_1s() const {return Qz_1s_;}
41 OperatorType Qp_1s() const {return Qp_1s_;}
42 OperatorType Qm_1s() const {return Qm_1s_;}
43 OperatorType Qpz_1s() const {return Qpz_1s_;}
44 OperatorType Qmz_1s() const {return Qmz_1s_;}
45
49
51
52protected:
53
54 std::size_t D;
55 int mfactor = 1;
56
57 void fill_basis();
59
61 typename Symmetry_::qType getQ (SPINOP_LABEL Sa) const;
62
64
65 OperatorType Id_1s_; // identity
67 OperatorType F_1s_; // fermionic sign
68
69 OperatorType n_1s_; // particle number
70
71 //orbital spin
75
76 //orbital quadrupole
82
86};
87
88template<typename Symmetry_, size_t order>
90SpinSite(std::size_t D_input, int mfactor_input)
91:D(D_input), mfactor(mfactor_input)
92{
93 //create basis for one spin site
94 fill_basis();
95
96 // cout << "single site basis" << endl << this->basis_1s_ << endl;
98}
99
100template<typename Symmetry_, size_t order>
103{
104 Id_1s_ = OperatorType(Symmetry::qvacuum(),basis_1s_);
105 Id_1s_.setIdentity();
106
107 Zero_1s_ = OperatorType(Symmetry::qvacuum(),basis_1s_);
108 Zero_1s_.setZero();
109
110 F_1s_ = OperatorType(Symmetry::qvacuum(),basis_1s_);
111
112 Sz_1s_ = OperatorType(getQ(SZ),basis_1s_);
113 Sp_1s_ = OperatorType(getQ(SP),basis_1s_);
114 Sm_1s_ = OperatorType(getQ(SM),basis_1s_);
115
116 if (D>2)
117 {
118 Qz_1s_ = OperatorType(getQ(SZ),basis_1s_);
119 Qp_1s_ = OperatorType(getQ(QP),basis_1s_);
120 Qm_1s_ = OperatorType(getQ(QM),basis_1s_);
121 Qpz_1s_ = OperatorType(getQ(SP),basis_1s_);
122 Qmz_1s_ = OperatorType(getQ(SM),basis_1s_);
123 }
124
125 exp_i_pi_Sz_1s_ = ComplexOperatorType(getQ(SZ),basis_1s_);
126 if constexpr (Symmetry::IS_TRIVIAL)
127 {
128 exp_i_pi_Sx_1s_ = OperatorType(getQ(SX),basis_1s_);
129 exp_i_pi_Sy_1s_ = OperatorType(getQ(iSY),basis_1s_);
130 }
131
132 OperatorType Sbase = OperatorType(getQ(SP),basis_1s_);
133
134 double S = 0.5*(D-1);
135 size_t Sx2 = D-1;
136
137 for (size_t i=0; i<D-1; ++i)
138 {
139 int Q = -static_cast<int>(Sx2) + 2*static_cast<int>(i);
140 int Qplus1 = Q+2; //note spacing of m is 2 because we deal with 2*m instead of m
141
142 stringstream ssQ; ssQ << Q;
143 stringstream ssQplus1; ssQplus1 << Qplus1;
144
145 double m = -S + static_cast<double>(i);
146 Sbase(ssQplus1.str(),ssQ.str()) = 0.5*sqrt(S*(S+1.)-m*(m+1.));
147 }
148
149 Sp_1s_ = 2.*Sbase;
150 Sm_1s_ = Sp_1s_.adjoint();
151 Sz_1s_ = 0.5 * (Sp_1s_*Sm_1s_ - Sm_1s_*Sp_1s_);
152
153 F_1s_ = 0.5*Id_1s_-Sz_1s_;
154
155// cout << "SpinSite:" << endl;
156// cout << "Sbase=" << endl << MatrixXd(Sbase.template plain<double>().data) << endl;
157// cout << "Sp=" << endl << MatrixXd(Sp_1s_.template plain<double>().data) << endl;
158// cout << "Sm=" << endl << MatrixXd(Sm_1s_.template plain<double>().data) << endl;
159
160 if (D>2)
161 {
162 Qz_1s_ = 1./sqrt(3.) * (3.*Sz_1s_*Sz_1s_-S*(S+1.)*Id_1s_);
163 Qp_1s_ = Sp_1s_*Sp_1s_;
164 Qm_1s_ = Sm_1s_*Sm_1s_;
165 Qpz_1s_ = Sp_1s_*Sz_1s_+Sz_1s_*Sp_1s_;
166 Qmz_1s_ = Sm_1s_*Sz_1s_+Sz_1s_*Sm_1s_;
167 }
168
169 if constexpr (Symmetry::IS_TRIVIAL)
170 {
171 // The exponentials are only correct for integer spin S=1,2,3,...!
172 //for (size_t i=0; i<D; ++i) // <- don't want this basis order
173 for (int i=D-1; i>=0; --i)
174 {
175 int Q1 = -static_cast<int>(Sx2) + 2*static_cast<int>(i);
176 int Q2 = +static_cast<int>(Sx2) - 2*static_cast<int>(i);
177 stringstream ssQ1; ssQ1 << Q1;
178 stringstream ssQ2; ssQ2 << Q2;
179
180 // exp(i*pi*Sx) has -1 on the antidiagonal for S=1,3,5,...
181 // and +1 for S=2,4,6,...
182 exp_i_pi_Sx_1s_(ssQ1.str(),ssQ2.str()) = pow(-1.,D);
183
184 // exp(i*pi*Sy) has alternating +-1 on the antidiagonal
185 // starting with -1 for even D and with +1 for odd D
186 exp_i_pi_Sy_1s_(ssQ1.str(),ssQ2.str()) = pow(-1.,D+1) * pow(-1,i);
187 }
188 }
189
190 //for (size_t i=0; i<D; ++i) // <- don't want this basis order
191 for (int i=D-1; i>=0; --i)
192 {
193 double m = -S + static_cast<double>(i);
194 int Q = -static_cast<int>(Sx2) + 2*static_cast<int>(i);
195 stringstream ssQ; ssQ << Q;
196 //exp_i_pi_Sz_1s_(ssQ.str(),ssQ.str()) = pow(-1.,m);
197 exp_i_pi_Sz_1s_(ssQ.str(),ssQ.str()) = exp(1.i*M_PI*m);
198 }
199
200 return;
201}
202
203template<typename Symmetry_, size_t order>
206{
207 if constexpr (Symmetry::NO_SPIN_SYM()) // U0
208 {
209 typename Symmetry::qType Q=Symmetry::qvacuum();
210 Eigen::Index inner_dim = D;
211 std::vector<std::string> ident;
212
213 assert(D >= 1);
214 double S = 0.5*(D-1);
215 size_t Sx2 = D-1;
216 //for (size_t i=0; i<D; ++i) // <- don't want this basis order
217 for (int i=D-1; i>=0; --i)
218 {
219 int Qint = -static_cast<int>(Sx2) + 2*static_cast<int>(i);
220 inner_dim=1;
221 stringstream ss; ss << Qint;
222 ident.push_back(ss.str());
223 }
224 basis_1s_.push_back(Q,inner_dim,ident);
225 }
226 else if constexpr (Symmetry::IS_SPIN_U1()) // spin U1
227 {
228 typename Symmetry::qType Q;
229 Eigen::Index inner_dim;
230 std::vector<std::string> ident;
231
232 assert(D >= 1);
233 double S = 0.5*(D-1);
234 size_t Sx2 = D-1;
235
236 //for (size_t i=0; i<D; ++i) // <- don't want this basis order
237 for (int i=D-1; i>=0; --i)
238 {
239 int Qint = -static_cast<int>(Sx2) + 2*static_cast<int>(i);
240 if constexpr (Symmetry::Nq>1)
241 {
242 if (Symmetry::kind()[0] == Sym::KIND::M and Symmetry::kind()[1] == Sym::KIND::M) // two U(1) symmetries: system-bath canonical
243 {
244 for (size_t q=0; q<Symmetry::Nq; q++)
245 {
246 if (Symmetry::kind()[q] == Sym::KIND::M and q==0)
247 {
248 Q[q] = (mfactor==1)? Qint:0;
249 }
250 else if (Symmetry::kind()[q] == Sym::KIND::M and q==1)
251 {
252 Q[q] = (mfactor==1)? 0:Qint;
253 }
254 else
255 {
256 Q[q] = Qint;
257 }
258 }
259 //cout << "i=" << i << ", Q=" << Q << endl;
260 }
261 else if (Symmetry::kind()[0] == Sym::KIND::M and Symmetry::kind()[1] != Sym::KIND::M)
262 {
263 Q[0] = Qint*mfactor;
264 Q[1] = Symmetry::S2::qvacuum()[0];
265 }
266 else if (Symmetry::kind()[0] != Sym::KIND::M and Symmetry::kind()[1] == Sym::KIND::M)
267 {
268 Q[0] = Symmetry::S1::qvacuum()[0];
269 Q[1] = Qint*mfactor;
270 }
271 }
272 else
273 {
274 //cout << "i=" << i << ", Q=" << Qint*mfactor << endl;
275 Q[0] = Qint*mfactor;
276 }
277 inner_dim = 1;
278 stringstream ss; ss << Qint;
279 ident.push_back(ss.str());
280 basis_1s_.push_back(Q, inner_dim, ident);
281 ident.clear();
282 }
283 }
284}
285
286template<typename Symmetry_, size_t order>
287typename Symmetry_::qType SpinSite<Symmetry_,order>::
288getQ (SPINOP_LABEL Sa) const
289{
290 if constexpr (Symmetry::NO_SPIN_SYM()) {return Symmetry::qvacuum();}
291 else if constexpr (Symmetry::Nq == 1)
292 {
293 if constexpr (Symmetry::kind()[0] == Sym::KIND::N or // particle number
294 Symmetry::kind()[0] == Sym::KIND::Nparity) // particle number parity
295 {
296 return Symmetry::qvacuum();
297 }
298 else if constexpr (Symmetry::kind()[0] == Sym::KIND::M) // magnetization
299 {
300 assert(Sa != SX and Sa != iSY);
301
302 typename Symmetry::qType out;
303 if (Sa==SZ or Sa==QZ) {out = {0};}
304 else if (Sa==SP or Sa==QPZ) {out = {+2*mfactor};}
305 else if (Sa==SM or Sa==QMZ) {out = {-2*mfactor};}
306 else if (Sa==QP) {out = {+4*mfactor};}
307 else if (Sa==QM) {out = {-4*mfactor};}
308 return out;
309 }
310 else {assert(false and "Ill defined KIND of the used Symmetry.");}
311 }
312 else if constexpr (Symmetry::Nq == 2) // implicitly S=1/2 here (fermions or system-bath U1xU1), adjust if required
313 {
314 assert(Sa != SX and Sa != iSY and Sa != QP and Sa != QM);
315
316 typename Symmetry::qType out;
317 if constexpr (Symmetry::kind()[0] == Sym::KIND::N and Symmetry::kind()[1] == Sym::KIND::M)
318 {
319 if (Sa==SZ) {out = {0,0};}
320 else if (Sa==SP) {out = {0,+2};}
321 else if (Sa==SM) {out = {0,-2};}
322 }
323 else if constexpr (Symmetry::kind()[0] == Sym::KIND::M and Symmetry::kind()[1] == Sym::KIND::N)
324 {
325 if (Sa==SZ) {out = {0,0};}
326 else if (Sa==SP) {out = {+2*mfactor,0};}
327 else if (Sa==SM) {out = {-2*mfactor,0};}
328 }
329 else if constexpr (Symmetry::kind()[0] == Sym::KIND::M and Symmetry::kind()[1] == Sym::KIND::T)
330 {
331 if (Sa==SZ) {out = {0,1};}
332 else if (Sa==SP) {out = {+2*mfactor,1};}
333 else if (Sa==SM) {out = {-2*mfactor,1};}
334 }
335 else if constexpr (Symmetry::kind()[0] == Sym::KIND::Nup and Symmetry::kind()[1] == Sym::KIND::Ndn)
336 {
337 if (Sa==SZ) {out = {0,0};}
338 else if (Sa==SP) {out = {+1,-1};}
339 else if (Sa==SM) {out = {-1,+1};}
340 }
341 else if constexpr (Symmetry::kind()[0] == Sym::KIND::Ndn and Symmetry::kind()[1] == Sym::KIND::Nup)
342 {
343 if (Sa==SZ) {out = {0,0};}
344 else if (Sa==SP) {out = {-1,+1};}
345 else if (Sa==SM) {out = {+1,-1};}
346 }
347 else if constexpr (Symmetry::kind()[0] == Sym::KIND::M and Symmetry::kind()[1] == Sym::KIND::M)
348 {
349 if (mfactor == 1) // mfactor=1: system site, mfactor=0: bath site
350 {
351 if (Sa==SZ) {out = {0,0};}
352 else if (Sa==SP) {out = {+2,0};}
353 else if (Sa==SM) {out = {-2,0};}
354 }
355 else
356 {
357 if (Sa==SZ) {out = {0,0};}
358 else if (Sa==SP) {out = {0,+2};}
359 else if (Sa==SM) {out = {0,-2};}
360 }
361 }
362// cout << "order=" << order << ", Sa=" << Sa << ", out=" << out << endl;
363 return out;
364 }
365 static_assert("You inserted a Symmetry which can not be handled by FermionBase.");
366}
367
368#endif //FERMIONSITE_H_
@ DN
Definition: DmrgTypedefs.h:38
@ UP
Definition: DmrgTypedefs.h:37
SPINOP_LABEL
Definition: DmrgTypedefs.h:60
@ QZ
Definition: DmrgTypedefs.h:60
@ iSY
Definition: DmrgTypedefs.h:60
@ QM
Definition: DmrgTypedefs.h:60
@ QP
Definition: DmrgTypedefs.h:60
@ SZ
Definition: DmrgTypedefs.h:60
@ SP
Definition: DmrgTypedefs.h:60
@ SX
Definition: DmrgTypedefs.h:60
@ QPZ
Definition: DmrgTypedefs.h:60
@ SM
Definition: DmrgTypedefs.h:60
@ QMZ
Definition: DmrgTypedefs.h:60
Definition: Qbasis.h:39
SiteOperatorQ< Symmetry, MatrixType_ > adjoint() const
OperatorType Qp_1s_
Definition: SpinSite.h:78
OperatorType Sm_1s() const
Definition: SpinSite.h:37
OperatorType Sm_1s_
Definition: SpinSite.h:74
OperatorType Qm_1s() const
Definition: SpinSite.h:42
OperatorType Zero_1s_
Definition: SpinSite.h:66
OperatorType Qm_1s_
Definition: SpinSite.h:79
OperatorType exp_i_pi_Sx() const
Definition: SpinSite.h:46
ComplexOperatorType exp_i_pi_Sz_1s_
Definition: SpinSite.h:85
OperatorType exp_i_pi_Sy_1s_
Definition: SpinSite.h:84
Qbasis< Symmetry > basis_1s_
Definition: SpinSite.h:63
OperatorType Sz_1s_
Definition: SpinSite.h:72
OperatorType Qmz_1s_
Definition: SpinSite.h:81
OperatorType F_1s() const
Definition: SpinSite.h:30
void fill_SiteOps()
Definition: SpinSite.h:102
OperatorType Qpz_1s() const
Definition: SpinSite.h:43
Symmetry_ Symmetry
Definition: SpinSite.h:18
SiteOperatorQ< Symmetry, Eigen::Matrix< complex< Scalar >, Eigen::Dynamic, Eigen::Dynamic > > ComplexOperatorType
Definition: SpinSite.h:20
OperatorType Qpz_1s_
Definition: SpinSite.h:80
OperatorType Qp_1s() const
Definition: SpinSite.h:41
OperatorType Qmz_1s() const
Definition: SpinSite.h:44
OperatorType exp_i_pi_Sx_1s_
Definition: SpinSite.h:83
std::size_t D
Definition: SpinSite.h:54
OperatorType Zero_1s() const
Definition: SpinSite.h:29
double Scalar
Definition: SpinSite.h:17
OperatorType n_1s() const
Definition: SpinSite.h:32
Symmetry_::qType getQ(SPINOP_LABEL Sa) const
Definition: SpinSite.h:288
SpinSite(std::size_t D_input, int mfactor_input=1)
Definition: SpinSite.h:90
void fill_basis()
Definition: SpinSite.h:205
OperatorType Qz_1s_
Definition: SpinSite.h:77
SpinSite()
Definition: SpinSite.h:24
OperatorType Sz_1s() const
Definition: SpinSite.h:35
OperatorType Id_1s_
Definition: SpinSite.h:65
ComplexOperatorType exp_i_pi_Sz() const
Definition: SpinSite.h:48
OperatorType Sp_1s_
Definition: SpinSite.h:73
OperatorType F_1s_
Definition: SpinSite.h:67
Qbasis< Symmetry > basis_1s() const
Definition: SpinSite.h:50
SiteOperatorQ< Symmetry, Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > > OperatorType
Definition: SpinSite.h:19
int mfactor
Definition: SpinSite.h:55
OperatorType Qz_1s() const
Definition: SpinSite.h:40
OperatorType Sp_1s() const
Definition: SpinSite.h:36
OperatorType n_1s_
Definition: SpinSite.h:69
OperatorType Id_1s() const
Definition: SpinSite.h:28
OperatorType exp_i_pi_Sy() const
Definition: SpinSite.h:47