Running QMC simulation
As an example of Quantum Monte Carlo simulation we present a simulation of the effective local moment of the impurity with decreasing temperature due to Kondo screening, with the semielliptical density of states used as a hybridization function.
First, we import all required python modules:
from pyalps.hdf5 import archive # hdf5 interface
import pyalps.cthyb as cthyb # the solver module
import matplotlib.pyplot as plt # for plotting results
from numpy import exp,log,sqrt,pi # some math
Now we generate a sequence of $10$ temperatures between $0.05$ and $100.0$ which are equidistant on a logarithmic scale
N_T = 10 # number of temperatures
Tmin = 0.05 # maximum temperature
Tmax = 100.0 # minimum temperature
Tdiv = exp(log(Tmax/Tmin)/N_T)
T=Tmax
Tvalues=[]
for i in range(N_T+1):
Tvalues.append(T)
T/=Tdiv
We set up the values of the onsite interaction, the number of time points, and the time limit for each simulation:
Uvalues=[0.,2.] # the values of the on-site interaction
N_TAU = 1000 # number of tau-points; must be large enough for the lowest temperature (set to at least 5*BETA*U)
runtime = 5 # solver runtime (in seconds)
Then we set up the parameters for the simulation:
values=[[] for u in Uvalues]
errors=[[] for u in Uvalues]
parameters=[]
for un,u in enumerate(Uvalues):
for t in Tvalues:
# prepare the input parameters; they can be used inside the script and are passed to the solver
parameters.append(
{
# solver parameters
'SWEEPS' : 1000000000, # sweeps to be done
'THERMALIZATION' : 1000, # thermalization sweeps to be done
'SEED' : 42, # random number seed
'N_MEAS' : 10, # number of sweeps after which a measurement is done
'N_ORBITALS' : 2, # number of 'orbitals', i.e. number of spin-orbital degrees of freedom or segments
'BASENAME' : "hyb.param_U%.1f_BETA%.3f"%(u,1/t), # base name of the h5 output file
'MAX_TIME' : runtime, # runtime of the solver per iteration
'VERBOSE' : 1, # whether to output extra information
'TEXT_OUTPUT' : 0, # whether to write results in human readable (text) format
# file names
'DELTA' : "Delta_BETA%.3f.h5"%(1/t), # file name of the hybridization function
'DELTA_IN_HDF5' : 1, # whether to read the hybridization from an h5 archive
# physical parameters
'U' : u, # Hubbard repulsion
'MU' : u/2., # chemical potential
'BETA' : 1/t, # inverse temperature
# measurements
'MEASURE_nnw' : 1, # measure the density-density correlation function (local susceptibility) on Matsubara frequencies
'MEASURE_time' : 0, # turn of imaginary-time measurement
# measurement parameters
'N_HISTOGRAM_ORDERS' : 50, # maximum order for the perturbation order histogram
'N_TAU' : N_TAU, # number of imaginary time points (tau_0=0, tau_N_TAU=BETA)
'N_MATSUBARA' : int(N_TAU/(2*pi)), # number of Matsubara frequencies
'N_W' : 1, # number of bosonic Matsubara frequencies for the local susceptibility
# additional parameters (used outside the solver only)
't' : 1, # hopping
'Un' : un, # interaction point
}
)
For each set of parameters, we set up the hybridization function
for parms in parameters:
ar=archive(parms['BASENAME']+'.out.h5','a')
ar['/parameters']=parms
del ar
print("creating initial hybridization...").
g=[]
I=complex(0.,1.)
mu=0.0
for n in range(parms['N_MATSUBARA']):
w=(2*n+1)*pi/parms['BETA']
g.append(2.0/(I*w+mu+I*sqrt(4*parms['t']**2-(I*w+mu)**2))) # use GF with semielliptical DOS
delta=[]
for i in range(parms['N_TAU']+1):
tau=i*parms['BETA']/parms['N_TAU']
g0tau=0.0;
for n in range(parms['N_MATSUBARA']):
iw=complex(0.0,(2*n+1)*pi/parms['BETA'])
g0tau+=((g[n]-1.0/iw)*exp(-iw*tau)).real # Fourier transform with tail subtracted
g0tau *= 2.0/parms['BETA']
g0tau += -1.0/2.0 # add back contribution of the tail
delta.append(parms['t']**2*g0tau) # delta=t**2 g
# write hybridization function to hdf5 archive (solver input)
ar=archive(parms['DELTA'],'w')
for m in range(parms['N_ORBITALS']):
ar['/Delta_%i'%m]=delta
del ar
Finally, we run the Monte Carlo simulation for each set of parameters.
for parms in parameters:
# solve the impurity model in parallel
cthyb.solve(parms)
After the simulation is finished, we obtain results for each set of parameters, postprocess them, and plot them.
for parms in parameters:
# extract the local spin susceptiblity
ar=archive(parms['BASENAME']+'.out.h5','w')
nn_0_0=ar['simulation/results/nnw_re_0_0/mean/value']
nn_1_1=ar['simulation/results/nnw_re_1_1/mean/value']
nn_1_0=ar['simulation/results/nnw_re_1_0/mean/value']
dnn_0_0=ar['simulation/results/nnw_re_0_0/mean/error']
dnn_1_1=ar['simulation/results/nnw_re_1_1/mean/error']
dnn_1_0=ar['simulation/results/nnw_re_1_0/mean/error']
nn = nn_0_0 + nn_1_1 - 2*nn_1_0
dnn = sqrt(dnn_0_0**2 + dnn_1_1**2 + ((2*dnn_1_0)**2) )
ar['chi']=nn/4.
ar['dchi']=dnn/4.
del ar
T=1/parms['BETA']
values[parms['Un']].append(T*nn[0])
errors[parms['Un']].append(T*dnn[0])
plt.figure()
plt.xlabel(r'$T$')
plt.ylabel(r'$4T\chi_{dd}$')
plt.title('Kondo screening of an impurity\n(using the hybridization expansion impurity solver)')
for un in range(len(Uvalues)):
plt.errorbar(Tvalues, values[un], yerr=errors[un], label="U=%.1f"%Uvalues[un])
plt.xscale('log')
plt.legend()
plt.show()
After that, you will have the following plot: