TBTK

Need a break? Support the development by playing Polarity Puzzles 
See more details about the Model in the API
The Model class is a container for the Hamiltonian, chemical potential, temperature, statistics, etc. It is best understood through an example, therefore consider a twolevel system described by the Hamiltonian
which can be written
where \(a_{00} = U_0\), \(a_{11} = U_1\), and \(a_{01} = a_{10} = V\). Further, assume that we will study the system at temperature T = 300K, chemical potential mu = 0, and for particles with FermiDirac statistics.
Letting U_0, U_1, and V be the numerical symbols for \(U_0, U_1\), and \(V\), we can implement the model as follows.
Here the operator<< is used to pass the HoppingAmplitudes to the Model. Also note the use of "+ HC" in the line
which is equivalent to
The final call to model.construct() creates a linearized Hilbert space basis for the Indices passed into the Model.
To see how a more complex Model can be set up, consider a magnetic impurity on top of a twodimensional substrate of size 51x51. We describe the substrate with the Hamiltonian
where \(\mathbf{i}\) is a twodimensional index, \(\sigma\) is a spin index, and \(\langle\mathbf{i}\mathbf{j}\rangle\) denotes summation over nearest neighbors. The impurity is described by
and is connected to the site (25, 25) in the substrate through
The total Hamiltonian is
We first note that an appropriate Index structure is {0, x, y, s} for the substrate and {1, s} for the impurity, where s means spin. Reading of the Hamiltonian terms above, we can tabulate the hopping amplitudes.
Hopping amplitude  Value  To Index  From Index 

\(a_{(0,x,y,\sigma),(0,x,y,\sigma)}\)  \(U_S\)  {0, x, y, s}  {0, x, y, s} 
\(a_{(0,x+1,y,\sigma),(0,x,y,\sigma)}\)  \(t\)  {0, x+1, y, s}  {0, x, y, s} 
\(a_{(0,x,y,\sigma),(0,x+1,y,\sigma)}\)  \(t\)  {0, x, y, s}  {0, x+1, y, s} 
\(a_{(0,x,y+1,\sigma),(0,x,y,\sigma)}\)  \(t\)  {0, x, y+1, s}  {0, x, y, s} 
\(a_{(0,x,y,\sigma),(0,x,y+1,\sigma)}\)  \(t\)  {0, x, y, s}  {0, x, y+1, s} 
\(a_{(1,\sigma),(1,\sigma)}\)  \(U_{Imp}\)  {1, s}  {1, s} 
\(a_{(1,\uparrow),(1,\uparrow)}\)  \(J\)  {1, 0}  {1, 0} 
\(a_{(1,\downarrow),(1,\downarrow)}\)  \(J\)  {1, 1}  {1, 1} 
\(a_{(0,25,25,\sigma),(1,\sigma)}\)  \(\delta\)  {0, 25, 25, s}  {1, s} 
\(a_{(1,\sigma),(0,25,25,\sigma)}\)  \(\delta\)  {1, s}  {0, 25, 25, s} 
The left column contains the analytic symbol, while the three other columns contain the corresponding information that is needed to create a HoppingAmplitude. Subindices that are not numeric values (or arrows) should be understood to be summed/looped over in the analytic/numeric expressions.
The line pairs (2 and 3), (4 and 5), and (9 and 10) are the Hermitian conjugates of each other. Further, line 7 and 8 can be combined into a single line if we write the amplitude as J(1  2s). Taking this into account, the table can be compressed into
Value  To Index  From Index  Add Hermitian conjugate 

\(U_S\)  {0, x, y, s}  {0, x, y, s}  
\(t\)  {0, x+1, y, s}  {0, x, y, s}  Yes 
\(t\)  {0, x, y+1, s}  {0, x, y, s}  Yes 
\(U_{Imp}\)  {1, s}  {1, s}  
\(J(1  2s)\)  {1, 0}  {1, 0}  
\(\delta\)  {0, 25, 25, s}  {1, s}  Yes 
It is now straight forward to implement the Model.
The conversion from the analytic Hamiltonian to the numeric Model was here done in quite some detail. However, with a bit of experience it is possible to read of the HoppingAmplitude parameters immediately from the Hamiltonian without having to write down any tables.
We finish this example with the advice to always utilize the Hermitian conjugate to its maximum, as we did above. Note in particular that we used this to only have \(x+1\) and \(y+1\) in the toIndex (and there are no \(x1\) or \(y1\)). In short, only forward hopping terms are explicit. This improves readability and reduces the chance of introducing errors.
In the example above, ifstatements were added inside the first loop to prevent HoppingAmplitudes from being added across the boundary. The code can be made more readable by using an IndexFilter, which allows for the handling of such exceptions to be separated from the main Model specification.
We here demonstrate how an IndexFilter can be used to create a square shaped geometry with a hole inside. To do so, we begin by defining the IndexFilter.
The Filter needs to know the size of the the system and the holes radius, therefore the constructor takes these as arguments and stores them in its private variables. The clone()function is required and should return a pointer to a copy of the Filter. Finally, the isIncluded()function is responsible for returning true or false depending on whether the given Index should be included in the Model or not. In this example, it first checks whether the Index is inside the excluded radius and returns false if this is the case. Otherwise, it returns true or false depending on whether or not the Index is inside the range [0, sizeX)x[0, sizeY).
With the Filter defined, a Model with the size 51x51 and a hole radius of 10 can be set up as follows.
Note the call to model.setFilter() and the fact that no ifstatements appear inside the loop.
We end this section with a note about substems with complex Index structures. Consider a Model with two subsystems Indexed by {0, x, spin} and {1, x, y, z, spin}, respectively. The IndexFilter needs to be able to handle both of these Index structures. For example, requesting index[4] in the isIncluded()function before knowing that the Index belongs to subsystem 1 is an error. Therefore, an appropriate implementation of the isIncluded()function would, in this case, look something like this.
The Model can recognize a block diagonal Hamiltonian under the condition that the block diagonal Subindices appear to the left in the Index. Consider a translationally invariant system that is blockdiagonal in kx, ky, and kz, but not in orbital or spin. If the Index structure {kx, ky, kz, orbital, spin} is used, the Model will be able to recognize the block structure. This can be utilized by some Solvers such as the BlockDiagonalizer to speed up calculations. If instead {kx, ky, orbital, kz, spin} is used, only the kx and ky Subindices will be recognized as block indices.