HofstadterBosons¶
full name: tenpy.models.hofstadter.HofstadterBosons
parent module:
tenpy.models.hofstadter
type: class
-
class
tenpy.models.hofstadter.
HofstadterBosons
(model_params)[source]¶ Bases:
tenpy.models.model.CouplingModel
,tenpy.models.model.MPOModel
Bosons on a square lattice with magnetic flux.
For now, the Hamiltonian reads:
\[\begin{split}H = - \sum_{x, y} \mathtt{Jx} (e^{i \mathtt{phi}_{x,y} } a^\dagger_{x+1,y} a_{x,y} + h.c.) \\ - \sum_{x, y} \mathtt{Jy} (e^{i \mathtt{phi}_{x,y} } a^\dagger_{x,y+1} a_{x,y} + h.c.) \\ + \sum_{x, y} \frac{\mathtt{U}}{2} n_{x,y} (n_{x,y} - 1) - \mathtt{mu} n_{x,y}\end{split}\]where \(e^{i \mathtt{phi}_{x,y} }\) is a complex Aharonov-Bohm hopping phase, depending on lattice coordinates and gauge choice (see
tenpy.models.hofstadter.gauge_hopping()
).All parameters are collected in a single dictionary model_params and read out with
get_parameter()
.- Parameters
- Lx, Lyint
Size of the simulation unit cell in terms of lattice sites.
- mx, myint
Size of the magnetic unit cell in terms of lattice sites.
- Nmaxint
Maximum number of bosons per site.
- fillingtuple
Average number of fermions per site, defined as a fraction (numerator, denominator) Changes the definition of
'dN'
in theBosonSite
.- Jx, Jy, mu, U: float
Hamiltonian parameters as defined above.
- bc_MPS{‘finite’ | ‘infinte’}
MPS boundary conditions along the x-direction. For ‘infinite’ boundary conditions, repeat the unit cell in x-direction. Coupling boundary conditions in x-direction are chosen accordingly.
- bc_x‘periodic’ | ‘open’
Boundary conditions in x-direction
- bc_y‘ladder’ | ‘cylinder’
Boundary conditions in y-direction.
- conserve{‘N’ | ‘parity’ | None}
What quantum number to conserve.
- orderstring
Ordering of the sites in the MPS, e.g. ‘default’, ‘snake’; see
ordering()
- phituple
Magnetic flux density, defined as a fraction (numerator, denominator)
- phi_extfloat
External magnetic flux ‘threaded’ through the cylinder.
- gauge‘landau_x’ | ‘landau_y’ | ‘symmetric’
Choice of the gauge used for the magnetic field. This changes the magnetic unit cell.
Methods
add_coupling
(self, strength, u1, op1, u2, …)Add twosite coupling terms to the Hamiltonian, summing over lattice sites.
add_coupling_term
(self, strength, i, j, …)Add a two-site coupling term on given MPS sites.
add_onsite
(self, strength, u, opname[, category])Add onsite terms to
onsite_terms
.add_onsite_term
(self, strength, i, op[, …])Add an onsite term on a given MPS site.
all_coupling_terms
(self)Sum of all
coupling_terms
.all_onsite_terms
(self)Sum of all
onsite_terms
.calc_H_MPO
(self[, tol_zero])Calculate MPO representation of the Hamiltonian.
calc_H_bond
(self[, tol_zero])calculate H_bond from
coupling_terms
andonsite_terms
.calc_H_bond_from_MPO
(self[, tol_zero])Calculate the bond Hamiltonian from the MPO Hamiltonian.
calc_H_onsite
(self[, tol_zero])Calculate H_onsite from self.onsite_terms.
coupling_strength_add_ext_flux
(self, …)Add an external flux to the coupling strength.
group_sites
(self[, n, grouped_sites])Modify self in place to group sites.
test_sanity
(self)Sanity check, raises ValueErrors, if something is wrong.
init_lattice
init_sites
init_terms
-
add_coupling
(self, strength, u1, op1, u2, op2, dx, op_string=None, str_on_first=True, raise_op2_left=False, category=None)¶ Add twosite coupling terms to the Hamiltonian, summing over lattice sites.
Represents couplings of the form \(\sum_{x_0, ..., x_{dim-1}} strength[loc(\vec{x})] * OP1 * OP2\), where
OP1 := lat.unit_cell[u1].get_op(op1)
acts on the site(x_0, ..., x_{dim-1}, u1)
, andOP2 := lat.unit_cell[u2].get_op(op2)
acts on the site(x_0+dx[0], ..., x_{dim-1}+dx[dim-1], u2)
. Possible combinationsx_0, ..., x_{dim-1}
are determined from the boundary conditions inpossible_couplings()
.The coupling strength may vary spatially, \(loc(\vec{x})\) indicates the lower left corner of the hypercube containing the involved sites \(\vec{x}\) and \(\vec{x}+\vec{dx}\).
The necessary terms are just added to
coupling_terms
; doesn’t (re)build the MPO.Deprecated since version 0.4.0: The arguments str_on_first and raise_op2_left will be removed in version 1.0.0.
- Parameters
- strengthscalar | array
Prefactor of the coupling. May vary spatially (see above). If an array of smaller size is provided, it gets tiled to the required shape.
- u1int
Picks the site
lat.unit_cell[u1]
for OP1.- op1str
Valid operator name of an onsite operator in
lat.unit_cell[u1]
for OP1.- u2int
Picks the site
lat.unit_cell[u2]
for OP2.- op2str
Valid operator name of an onsite operator in
lat.unit_cell[u2]
for OP2.- dxiterable of int
Translation vector (of the unit cell) between OP1 and OP2. For a 1D lattice, a single int is also fine.
- op_stringstr | None
Name of an operator to be used between the OP1 and OP2 sites. Typical use case is the phase for a Jordan-Wigner transformation. The operator should be defined on all sites in the unit cell. If
None
, auto-determine whether a Jordan-Wigner string is needed, usingop_needs_JW()
.- str_on_firstbool
Whether the provided op_string should also act on the first site. This option should be chosen as
True
for Jordan-Wigner strings. When handling Jordan-Wigner strings we need to extend the op_string to also act on the ‘left’, first site (in the sense of the MPS ordering of the sites given by the lattice). In this case, there is a well-defined ordering of the operators in the physical sense (i.e. which of op1 or op2 acts first on a given state). We follow the convention that op2 acts first (in the physical sense), independent of the MPS ordering. Deprecated.- raise_op2_leftbool
Raise an error when op2 appears left of op1 (in the sense of the MPS ordering given by the lattice). Deprecated.
- categorystr
Descriptive name used as key for
coupling_terms
. Defaults to a string of the form"{op1}_i {op2}_j"
.
Examples
When initializing a model, you can add a term \(J \sum_{<i,j>} S^z_i S^z_j\) on all nearest-neighbor bonds of the lattice like this:
>>> J = 1. # the strength >>> for u1, u2, dx in self.lat.pairs['nearest_neighbors']: ... self.add_coupling(J, u1, 'Sz', u2, 'Sz', dx)
The strength can be an array, which get’s tiled to the correct shape. For example, in a 1D
Chain
with an even number of sites and periodic (or infinite) boundary conditions, you can add alternating strong and weak couplings with a line like:>>> self.add_coupling([1.5, 1.], 0, 'Sz', 0, 'Sz', dx)
To add the hermitian conjugate, e.g. for a hopping term, you should add it in the opposite direction
-dx
, complex conjugate the strength, and take the hermitian conjugate of the operators in swapped order (including a swap of u1 <-> u2). For spin-less fermions (FermionSite
), this would be>>> t = 1. # hopping strength >>> for u1, u2, dx in self.lat.pairs['nearest_neighbors']: ... self.add_coupling(t, u1, 'Cd', u2, 'C', dx) ... self.add_coupling(np.conj(t), u2, 'Cd', u1, 'C', -dx) # h.c.
With spin-full fermions (
SpinHalfFermions
), it could be:>>> for u1, u2, dx in self.lat.pairs['nearest_neighbors']: ... self.add_coupling(t, u1, 'Cdu', u2, 'Cd', dx) # Cdagger_up C_down ... self.add_coupling(np.conj(t), u2, 'Cdd', u1, 'Cu', -dx) # h.c. Cdagger_down C_up
Note that the Jordan-Wigner strings are figured out automatically!
-
add_coupling_term
(self, strength, i, j, op_i, op_j, op_string='Id', category=None)¶ Add a two-site coupling term on given MPS sites.
Wrapper for
self.coupling_terms[category].add_coupling_term(...)
.- Parameters
- strengthfloat
The strength of the coupling term.
- i, jint
The MPS indices of the two sites on which the operator acts. We require
0 <= i < N_sites
andi < j
, i.e., op_i acts “left” of op_j. If j >= N_sites, it indicates couplings between unit cells of an infinite MPS.- op1, op2str
Names of the involved operators.
- op_stringstr
The operator to be inserted between i and j.
- categorystr
Descriptive name used as key for
coupling_terms
. Defaults to a string of the form"{op1}_i {op2}_j"
.
-
add_onsite
(self, strength, u, opname, category=None)¶ Add onsite terms to
onsite_terms
.Adds a term \(\sum_{x_0, ..., x_{dim-1}} strength[x_0, ..., x_{dim-1}] * OP\), where the operator
OP=lat.unit_cell[u].get_op(opname)
acts on the site given by a lattice index(x_0, ..., x_{dim-1}, u)
, to the represented Hamiltonian.The necessary terms are just added to
onsite_terms
; doesn’t rebuild the MPO.- Parameters
- strengthscalar | array
Prefactor of the onsite term. May vary spatially. If an array of smaller size is provided, it gets tiled to the required shape.
- uint
Picks a
Site
lat.unit_cell[u]
out of the unit cell.- opnamestr
valid operator name of an onsite operator in
lat.unit_cell[u]
.- categorystr
Descriptive name used as key for
onsite_terms
. Defaults to opname.
-
add_onsite_term
(self, strength, i, op, category=None)¶ Add an onsite term on a given MPS site.
Wrapper for
self.onsite_terms[category].add_onsite_term(...)
.- Parameters
- strengthfloat
The strength of the term.
- iint
The MPS index of the site on which the operator acts. We require
0 <= i < L
.- opstr
Name of the involved operator.
- categorystr
Descriptive name used as key for
onsite_terms
. Defaults to op.
-
all_coupling_terms
(self)¶ Sum of all
coupling_terms
.
-
all_onsite_terms
(self)¶ Sum of all
onsite_terms
.
-
calc_H_MPO
(self, tol_zero=1e-15)¶ Calculate MPO representation of the Hamiltonian.
Uses
onsite_terms
andcoupling_terms
to build an MPO graph (and then an MPO).- Parameters
- tol_zerofloat
Prefactors with
abs(strength) < tol_zero
are considered to be zero.
- Returns
- H_MPO
MPO
MPO representation of the Hamiltonian.
- H_MPO
-
calc_H_bond
(self, tol_zero=1e-15)¶ calculate H_bond from
coupling_terms
andonsite_terms
.- Parameters
- tol_zerofloat
prefactors with
abs(strength) < tol_zero
are considered to be zero.
- Returns
- H_bondlist of
Array
Bond terms as required by the constructor of
NearestNeighborModel
. Legs are['p0', 'p0*', 'p1', 'p1*']
- H_bondlist of
- Raises
- ValueErrorif the Hamiltonian contains longer-range terms.
-
calc_H_bond_from_MPO
(self, tol_zero=1e-15)¶ Calculate the bond Hamiltonian from the MPO Hamiltonian.
- Parameters
- tol_zerofloat
Arrays with norm < tol_zero are considered to be zero.
- Returns
- H_bondlist of
Array
Bond terms as required by the constructor of
NearestNeighborModel
. Legs are['p0', 'p0*', 'p1', 'p1*']
- H_bondlist of
- Raises
- ValueErrorif the Hamiltonian contains longer-range terms.
-
calc_H_onsite
(self, tol_zero=1e-15)¶ Calculate H_onsite from self.onsite_terms.
Deprecated since version 0.4.0: This function will be removed in 1.0.0. Replace calls to this function by
self.all_onsite_terms().remove_zeros(tol_zero).to_Arrays(self.lat.mps_sites())
.- Parameters
- tol_zerofloat
prefactors with
abs(strength) < tol_zero
are considered to be zero.
- Returns
- H_onsitelist of npc.Array
onsite terms of the Hamiltonian.
-
coupling_strength_add_ext_flux
(self, strength, dx, phase)¶ Add an external flux to the coupling strength.
When performing DMRG on a “cylinder” geometry, it might be useful to put an “external flux” through the cylinder. This means that a particle hopping around the cylinder should pick up a phase given by the external flux [Resta1997]. This is also called “twisted boundary conditions” in literature. This function adds a complex phase to the strength array on some bonds, such that particles hopping in positive direction around the cylinder pick up exp(+i phase).
Warning
For the sign of phase it is important that you consistently use the creation operator as op1 and the annihilation operator as op2 in
add_coupling()
.- Parameters
- strengthscalar | array
The strength to be used in
add_coupling()
, when no external flux would be present.- dxiterable of int
Translation vector (of the unit cell) between op1 and op2 in
add_coupling()
.- phaseiterable of float
The phase of the external flux for hopping in each direction of the lattice. E.g., if you want flux through the cylinder on which you have an infinite MPS, you should give
phase=[0, phi]
souch that particles pick up a phase phi when hopping around the cylinder.
- Returns
- strengthcomplex array
The strength array to be used as strength in
add_coupling()
with the given dx.
Examples
Let’s say you have an infinite MPS on a cylinder, and want to add nearest-neighbor hopping of fermions with the
FermionSite
. The cylinder axis is the x-direction of the lattice, so to put a flux through the cylinder, you want particles hopping around the cylinder to pick up a phase phi given by the external flux.>>> strength = 1. # hopping strength without external flux >>> phi = np.pi/4 # determines the external flux strength >>> strength_with_flux = self.coupling_strength_add_ext_flux(strength, dx, [0, phi]) >>> for u1, u2, dx in self.lat.pairs['nearest_neighbors']: ... self.add_coupling(strength_with_flux, u1, 'Cd', u2, 'C', dx) ... self.add_coupling(np.conj(strength_with_flux), u2, 'Cd', u1, 'C', -dx)
-
group_sites
(self, n=2, grouped_sites=None)¶ Modify self in place to group sites.
Group each n sites together using the
GroupedSite
. This might allow to do TEBD with a Trotter decomposition, or help the convergence of DMRG (in case of too long range interactions).This has to be done after finishing initialization and can not be reverted.
- Parameters
- nint
Number of sites to be grouped together.
- grouped_sitesNone | list of
GroupedSite
The sites grouped together.
- Returns
- grouped_siteslist of
GroupedSite
The sites grouped together.
- grouped_siteslist of
-
test_sanity
(self)¶ Sanity check, raises ValueErrors, if something is wrong.