# Spectra of 1D quantum systems

In this tutorial we will calculate the spectra of the quantum Heisenberg model on various one-dimensional lattices. The main work will be done by the sparsediag application, which implements the Lanczos algorithm, an iterative eigensolver.

## Heisenberg chain

### Preparing and running the simulation from the command line

First, we look at a chain of S=1/2 spins with Heisenberg coupling. The parameter file parm_chain sets up ED simulations for the S_z=0 sector of chains with {L=10,...16} spins.

```   LATTICE = "chain lattice",
MODEL = "spin",
local_S = 0.5,
J = 1,
CONSERVED_QUANTUMNUMBERS = "Sz"
Sz_total = 0
{ L = 10; }
{ L = 12; }
{ L = 14; }
{ L = 16; }
```

Using the following sequence of commands you can run the diagonalization, then look at the output file parm_chain.out.xml with your browser.

```parameter2xml parm_chain
sparsediag --write-xml parm_chain.in.xml
```

### Preparing and running the simulation using Python

To set up and run the simulation in Python, we use the script chain.py. You can run it with the convenience scripts alpspython or vispython.

Looking at the different parts of the script, we see how the input files are prepared as a list of Python dictionaries after importing the required modules.

```import pyalps
import numpy as np
import matplotlib.pyplot as plt
import pyalps.pyplot

parms=[]
for l in [10, 12, 14, 16]:
parms.append(
{
'LATTICE'                   : "chain lattice",
'MODEL'                     : "spin",
'local_S'                   : 0.5,
'J'                         : 1,
'L'                         : l,
'CONSERVED_QUANTUMNUMBERS'  : 'Sz',
'Sz_total'                  : 0
}
)
```

Next, the input parameters are written into XML job files an the sparsediag simulation is run.

```input_file = pyalps.writeInputFiles('parm_chain',parms)
res = pyalps.runApplication('sparsediag',input_file)
```

For plotting the spectrum, we then load the HDF5 files produced by the simulation

```data = pyalps.loadSpectra(pyalps.getResultFiles(prefix='parm_chain'))
```

and collect the energies from all momentum sectors into one DataSet for each system size L. For getting a nice plot we additionally subtract the ground state energy from all eigenvalues and assign a label and line style to each spectrum.

```spectra = {}
for sim in data:
l = int(sim.props['L'])
all_energies = []
spectrum = pyalps.DataSet()
for sec in sim:
all_energies += list(sec.y)
spectrum.x = np.concatenate((spectrum.x,np.array([sec.props['TOTAL_MOMENTUM'] for i in range(len(sec.y))])))
spectrum.y = np.concatenate((spectrum.y,sec.y))
spectrum.y -= np.min(all_energies)
spectrum.props['line'] = 'scatter'
spectrum.props['label'] = 'L='+str(l)
spectra[l] = spectrum
```

Now the spectra from different system sizes can be plotted into one figure:

```plt.figure()
pyalps.pyplot.plot(spectra.values())
plt.legend()
plt.title('Antiferromagnetic Heisenberg chain (S=1/2)')
plt.ylabel('Energy')
plt.xlabel('Momentum')
plt.xlim(0,2*3.1416)
plt.ylim(0,2)
plt.show()
```

### Setting up and running the simulation in Vistrails

To run the simulation in Vistrails open the file ed-03-spectra.vt and look at the workflow labeled "Chain". Click on "Execute" to prepare the input file, run the simulation and create the output figure.

With only a few small changes to the input parameters used above, we can calculate the spectrum of a two-leg ladder of Heisenberg spins. The new parameter text file parm_ladder looks like this:

```LATTICE = "ladder"
MODEL = "spin"
local_S = 0.5
J0 = 1
J1 = 1
CONSERVED_QUANTUMNUMBERS = "Sz"
Sz_total = 0
{ L = 6; }
{ L = 8; }
{ L = 10; }
```

We have just replaced the "chain lattice" by a "ladder" and defined two separate coupling constants J0, J1 for the legs and the rungs, respectively. Apart from that, we have reduced the linear system size L because the ladder has 2 L spins. The same changes have to be made to the Python code, which can be downloaded from here: ladder.py

The corresponding Vistrails workflow can again be found in the file ed-03-spectra.vt. In the history view select the workflow labeled "Ladder".

## Isolated dimers

If we set the coupling on the legs of the ladder J0 = 0, we get the spectrum of L isolated dimers. This is done in the parameter file parm_dimers, the Python script dimers.py and the workflow labeled "Isolated dimers" in the file ed-03-spectra.vt.

## Questions

• Observe how putting together spectra from different system sizes produces nice bands
• In the spectrum of the Heisenberg ladder: Identify continuum and bound states
• What is the major difference between the chain and the ladder spectrum?
• Explain the spectrum of isolated dimers
• Vary the coupling constants in the ladder and observe how the spectrum changes between the limits discussed before
• Bonus question: Have a close look at the spectrum of the chain for different system sizes: There seems to be a difference between cases where L/2 is even and those where it is odd. Can you explain this? What happens in the TDL where L goes to infinity?