Activating
project at `~/ResearchTidbits/posts/phase-diagram`
Given a quantum many-body Hamiltonian, one of the first goals usually is to account for possible ground state phases and map out the corresponding phase diagram in the parameter space. Generally, each phase is associated with an observable called the order parameter that only takes a non-zero value if the ground state is in that particular phase. Plotting out the phase diagram then just becomes a matter of determining the regions where various order parameters vanish.
While solving the whole many-body problem is a computationally expensive task, we will try to show that plotting the phase diagram does not necessarily require the entire information contained in the ground state, allowing us to make some smart optimizations.
The Bose-Hubbard model
Let us consider a really simple system for demonstrating this; the 1D Bose-Hubbard model which describes interacting bosons in an optical lattice. What follows is largely based on things I worked on during my master’s thesis, so I will skip some details that can be found there. The Hamiltonian for the system is given as follows:
where
Examining the limiting cases of Hamiltonian, we can get an idea of the possible ground state phases of the system. In the limit of
(*Strictly speaking, what we have is a superfluid phase since a true BEC may not occur in 1D at any temperature. However, in what follows we will work in the mean-field limit where we explicitly break the
A mean-field analysis
While we could proceed with a full many-body simulation, perhaps using matrix product states, the point can be made just at the level of a mean-field. Note that from a physics standpoint, the mean-field approach is absolutely terrible in 1 dimension as it ignores quantum fluctuations which are dominant in lower dimensions. As such, the rest of this post should be treated as an overview of numerical trickeries involved rather than a truthful display of the nature of the phase transition of the full many-body system.
The mean field approach proceeds as follows: (1) we first decompose the creation operator in terms of its expectation value with the ground state,
We see that this is now a set of self-consistent equations and we need to find the fixed point of
A naive phase diagram
We will solve this self-consistent system using the most naive technique; fixed-point iteration. Basically, we begin with some initial guess
# cutoff necessary since bosonic space is infinite dimensional
mean_field_ops(nmax) = (diagm(1 => sqrt.(1:nmax)), diagm(0 => 0:nmax))
BHM(â, n̂; t, mu, psi, U=1.0) = -mu * n̂ + 0.5 * U * n̂ * (n̂ - I) - 2t * psi * (â + â') + 2t * psi^2 * I
function solve(â, n̂, H; atol=1e-8, callback=identity)
# initial guess
= rand(eltype(â), size(â, 1))
state = state' * â * state
psi = psi
psi_old
while true
## f(psi)
= eigvecs(H(psi))[:, 1]
state ./= sqrt(norm(state))
state = state' * â * state
psi ##
# check convergence
norm(psi - psi_old) < atol) && break
(= psi
psi_old
# for injecting other custom logic later on; by default it does nothing
callback(psi)
end
return state, psi
end
solve(â, n̂; t, mu, atol=1e-8) = solve(â, n̂, psi -> BHM(â, n̂, t=t, mu=mu, psi=psi), atol=atol)
solve (generic function with 2 methods)
We can now plot a naive phase diagram by simply looping over a grid of parameter values and visualizing the magnitude of the order parameter.
begin
= mean_field_ops(4)
â, n̂ = 50
npoints = range(0.0, 0.12, npoints)
ts = range(0.0, 3.0, npoints)
mus = zeros(length(mus), length(ts))
res
# can be multi-threaded since each computation is entirely independant from the others
Threads.@threads for idx in CartesianIndices(res)
= psi -> BHM(â, n̂, t=ts[idx.I[2]], mu=mus[idx.I[1]], psi=psi)
H = solve(â, n̂, H)
_, res[idx] end
heatmap(ts, mus, res)
end
As expected, there are Mott insulator lobes where the order parameter vanishes and there is a second order transition to the superfluid phase where
Since we know that what we’re looking for is a fixed point, we might expect that simply checking whether
# callback to record data on every iteration
struct RecordObservable{T}
::Vector{T}
dataend
::RecordObservable)(psi) = push!(o.data, psi)
(o
function convergence_plot(t, mu; n=7, xlims)
= plot(framestyle=:box, ylabel="Order parameter", xlabel="Number of iterations", title="\n(t=$t | mu=$mu)", legend=:topright, xlims=xlims)
p
= RecordObservable(Float64[])
history
for _ in 1:n
= RecordObservable(Float64[])
history solve(â, n̂, psi -> BHM(â, n̂, t=t, mu=mu, psi=psi), callback=history)
plot!(history.data, lab="", ls=:dashdot, lw=1.5)
end
hline!([history.data[end]], c=:black, lw=2, alpha=0.75, lab="Converged value")
return p
end
display(plot(convergence_plot(0.06, 0.5, xlims=[1, 20]), convergence_plot(0.1, 0.5, xlims=[1, 20]), size=(1000, 400), margins=10Plots.mm))
We see that the convergence proceeds strictly monotonically towards the stable fixed point. This means that all we need to do is begin with
function isSuperfluid(H; psi=1e-8)
## f(psi)
= eigvecs(H(psi))[:, 1]
state ./= sqrt(norm(state))
state return (state' * â * state) > psi
end
= zeros(length(mus), length(ts))
res
Threads.@threads for idx in CartesianIndices(res)
= psi -> BHM(â, n̂, t=ts[idx.I[2]], mu=mus[idx.I[1]], psi=psi)
H = isSuperfluid(H)
res[idx] end
heatmap(ts, mus, res)
This is already great, but we can do even better. Notice how for a given value of
function bisection(f, low, high; atol=1e-8)
= 0
mid
while !isapprox(low, high, atol=atol)
= (low + high) / 2
mid
if f(mid)
= mid
low else
= mid
high end
end
return mid
end
= range(0.0, 3.0, length=100)
mus = zeros(size(mus))
ts Threads.@threads for idx in eachindex(mus)
= bisection(t -> !isSuperfluid(psi -> BHM(â, n̂, t=t, mu=mus[idx], psi=psi)), 0.0, 0.1)
ts[idx] end
plot(ts, mus, legend=:topright, lw=2, c=:black, lab="")
scatter!(ts, mus, c=:black, lab="", xlims=[0, 0.12])
To obtain a boundary of similar resolution by solving for the ground state in an entire grid of parameter values would be several orders of magnitude slower and wasteful in terms of the information that we actually utilize. Of course, there are tons of information in the actual ground state such as the correlations in the system that provide more insight into the nature of the phase transition, but these are not required if all we want is a boundary. Such a scheme would still work if there are more than two phases although more book-keeping may be involved to find a combination of order parameters to serve as a binary quantity to identify each regime.
Finally, we note that obviously the observations involved here were specific to the fact that the mean-field approach resulted in a self-consistent set of equations. Furthermore, if the phase boundary gets more complex, for example, with two jumps in