Download this notebook (.ipynb + data files)
7. AutoHF Crash Course#
In this tutorial, we will cover the basics of using AutoHF for the purpose of generating trial wavefunctions for SAFIRE.
π οΈ To cover:
providing a Hamiltonian
pinning fields!!
characterizing the HF SD
charge and spin densities
spin-spin correlation
using sufficient parallel trials.
choosing the ansatz
choosing the optimization method.
7.1. Software Preliminaries#
While AutoHF is a stand alone tool with itβs own input format for Hamiltonians. However, it is able to convert SAFIRE format hamiltonians to itβs own internal format very easily. In this tutorial, we will exclusively use afqmctools to build Hamiltonians, then use the SAFIRE to AutoHF converter to provide AutoHF with the desired Hamiltonian.
7.2. βΆοΈ Run the cell below to setup the tutorial#
%load_ext autoreload
%autoreload
from pathlib import Path
# simple setup
from tutorial_utils import run_afqmc
scratch_dir = Path("data")
scratch_dir.mkdir(parents=True, exist_ok=True)
7.3. Set up the model#
In this tutorial, we will perform Hartree-Fock calculations using AutoHF for the Hubbard model on a 4x4 lattice. The Hamiltonian is given by,
from afqmctools.hamiltonian.model.director import HamiltonianDirector
import afqmctools.utils.io as io
from afqmctools.systems.lattice import get_lattice
import afqmctools.utils.visualize as vis
lattice_params = dict(
L1 = 4,
L2 = 4,
boundary1 = 'PBC',
boundary2 = 'PBC',
)
lattice = get_lattice(
params=lattice_params
)
vis.plot_lattice(lattice)
# Step 2. define Hamiltonian parameters
hamiltonian_params = {
'hamiltonian' : {
"t" : 1.0, # note: we could omit this, nearest-neighbor hoping with t=1 is included by default
"U" : 4.0
}
}
# Step 3.b. build the lattice model Ha
hamiltonian = HamiltonianDirector(
lattice=lattice,
source=hamiltonian_params
).build()
We now have a βstandardβ Hubbard model with nearest-neighbor hopping and onsite U in the hamiltonian object.
7.4. Setting up a calculation in AutoHF#
AutoHF requires only two inputs.
a Hamiltonian in the AutoHF format
Python dictionary containing settings
7.4.1. 1. Getting a Hamiltonian in AutoHF#
We can easily convert afqmctools Hamiltonians to the AutoHF format using,
from autohf import AutoHFHamiltonian
hamiltonian_autohf=AutoHFHamiltonian(source=hamiltonian_safire)
where hamiltonian_safire is a Hamiltonian generated by afqmctools, and
hamiltonian_autohf is the same Hamiltonian in the AutoHF format.
7.4.2. 2. AutoHF settings dictionary#
AutoHF is controlled via a Python dictionary containing various keyword arguments. Think of this as an input file. Below is a sample settings dictionary with most common settings exposed.
hf_settings = dict(
ansatz = 'SD',
steps = 100,
nelec = (5,5),
batch_size = 30,
seed = 42,
measure_spin = True,
noncollinear = False,
verbose = False,
riemannian = False
)
Covering all of the settings is beyond the scope of this tutorial; however, we will focus on a few key settings which are as follows.
ansatzstepsbatch_size
When you run AutoHF, it will echo the settings. See sample output below.
-----------------------
- βββ ------- β ββββ --
- β ββ£ ββββ¦βββ β ββ£β β ---
- β β ββ β ββ β ββ¨ ----
-----------------------
===== AutoHF Settings =====
noncollinear True
gpu False
approx_expm False
force_complex False
ansatz SD
opt_method lbfgs
riemannian False
seed 42
eta 0.1
steps 100
batch_size 100
plot False
verbose False
output None
dump_batch False
measure_spin True
random_initial_phi0 False
state0_scale 0.01
7.5. βΆοΈ Your Turn: Trying running AutoHF for the 4x4 Hubbard Model#
Complete the labelled line of code and run the cell below.
from autohf import lattice_hf,AutoHFHamiltonian
from afqmctools.inputs.from_autohf import autohf_to_afqmc
# "hamiltonian" contains the afqmctools format Hamiltonian
hamiltonian_autohf = AutoHFHamiltonian(hamiltonian) # Your Turn: convert to the autoHF format
# define settings
hf_settings = dict(
ansatz = 'SD',
steps = 100,
nelec = (5,5),
batch_size = 30,
seed = 42,
measure_spin = True,
random_initial_phi0 = False,
noncollinear = True,
verbose = False
)
results = lattice_hf(
hamiltonian=hamiltonian_autohf,
settings=hf_settings
)
7.6. β Solution#
You should have completed the line of code as,
# "hamiltonian" contains the afqmctools format Hamiltonian
hamiltonian_autohf = AutoHFHamiltonian(hamiltonian)
You should have gotten a HF energy of -17.7499999549238 \(t\) (to within about \(1 \times 10^{-8} t\)) when you ran AutoHF.
autohf_to_afqmc(
results,
output_fname = scratch_dir/"uhf_wfn.h5"
)
7.7. Analyzing the HF Wavefunction#
It is very important to analyze / characterize the HF solution before using it as a trial wavefunction to ensure that it is the desired properties.
# get the density from autohf
state_results, functions = results
makeRDMs = functions['makeRDMs']
state = state_results['state']
rdm = makeRDMs(state)
# get lattice dimensions from the Lattice instance
L = lattice.L
# collinear
#rho_up = rdm[0].diagonal().reshape(*L)
#rho_down = rdm[1].diagonal().reshape(*L)
# noncollinear
M = lattice.N_sites
rho_up = rdm[:M,:M].diagonal().reshape(*L)
rho_down = rdm[M:,M:].diagonal().reshape(*L)
rho_charge = rho_up + rho_down
rho_spin = rho_up - rho_down
vis.plot_lattice(
lattice,
density=rho_charge.real,
density_label="charge density",
vmin=0.0,
vmax=2.0
)
from afqmctools.observables.spin import local_spin
vis.plot_lattice(
lattice,
density=rho_spin,
density_label="spin density",
cmap="bwr",
vmin=-0.5,
vmax=0.5
)