11. Adding Custom Terms to the Hamiltonian#
This advanced example covers adding a manually-constructed one-body term to a lattice model Hamiltonian by directly invoking the HamiltonianBuilder.
import scipy.sparse as sps
import numpy as np
from afqmctools.systems.lattice import get_lattice
from afqmctools.hamiltonian.model.builder import HamiltonianBuilder
from afqmctools.hamiltonian.model.ham_class import HamiltonianComponent,SpinSymm
import afqmctools.utils.io as io
from afqmctools.wavefunction.free_electron import free_electron
lattice = get_lattice(
params=dict(
L1 = 3,
L2 = 2,
boundary1 = "PBC",
boundary2 = "PBC"
)
)
nelec = (2,2)
builder = HamiltonianBuilder(lattice=lattice)
# add some terms
builder.nth_neighbor_hopping(t=[1.0,0.5])
builder.onsite_hubbard(U=8.0)
builder.nth_order_hubbard_Vij(V=2.0)
nbasis = lattice.N_sites
# add a custom term - in this case, randon symetric noise
one_body_matrix = 0.0001*np.random.rand(nbasis,nbasis)
one_body_matrix = sps.csr_matrix(0.5*(one_body_matrix + one_body_matrix.T))
# the convention is to stack the spin-up hopping matrix on the spin-down hopping matrix
one_body_matrix = sps.vstack([one_body_matrix,one_body_matrix])
custom_one_body = HamiltonianComponent(
csr_matrix=one_body_matrix,
model_type='one_body',
spin_symm=SpinSymm.COLLINEAR
)
# manually add the custom term
builder.hamiltonian["tij"] = custom_one_body
builder.finalize()
hamiltonian = builder.hamiltonian
io.write_model_hamiltonian(
hamiltonian=hamiltonian,
fname="afqmc.h5",
nelec=nelec
)
free_electron(
source=hamiltonian,
nelec=nelec,
output="afqmc.h5",
lattice=lattice
)
If the sample Python script is run above with the sample input file, the following should be present at the end of the output.
computing and storing 1th-nearest neighbors
Computing distance matrix of lattice
Reading lattice site positions from Lattice
computing and storing 1th-nearest image neighbors
computing and storing 2th-nearest neighbors
computing and storing 2th-nearest image neighbors
Building Hubbard U term with U=8.0
Building onsite hubbard with positive U values: 8.0
Building Hubbard-Kanamori density-density U1 term with U1=2.0
Building hubbard term with positive U values: (0, 0) 2.0
H_U = (0, 1) 4.0
(0, 2) 2.0
(0, 4) 2.0
(1, 3) 2.0
(1, 5) 2.0
(2, 3) 4.0
(2, 4) 2.0
(3, 5) 2.0
(4, 5) 4.0
Building Hubbard-Kanamori spin-spin U2 term with U2=2.0
Building hubbard term with positive U values: (0, 0) 2.0
H_U = (0, 1) 4.0
(0, 2) 2.0
(0, 4) 2.0
(1, 3) 2.0
(1, 5) 2.0
(2, 3) 4.0
(2, 4) 2.0
(3, 5) 2.0
(4, 5) 4.0
Combining terms of the same type
Combining tij terms
Combining Hubbard U, U1, and U2 terms where possible
Max spin symmetry is SpinSymm.COLLINEAR
Generating free-electron trial wavefunction with twist = [4.10803005e-06 4.58334805e-04]
using dense representation of 1-body Hamiltonian to find eigenvalues and orbitals
Eigenvalues of the non-interacting Hamiltonian: [-5.67587361 -0.50001411 0.17622459 1.499989 1.9999482 2.50000033]
using dense representation of 1-body Hamiltonian to find eigenvalues and orbitals
Eigenvalues of the non-interacting Hamiltonian: [-5.67587361 -0.50001411 0.17622459 1.499989 1.9999482 2.50000033]
-----------------------
- ╔═╗ ------- ╖ ╓╔═╕ --
- ╠═╣ ╖╖╒╦╕╔╗ ╠═╣╠╕ ---
- ╜ ╙ ╚╝ ╜ ╚╝ ╜ ╙╨ ----
-----------------------
===== AutoHF Settings =====
inputfile input.toml
noncollinear False
gpu False
approx_expm False
force_complex False
ansatz SD
opt_method lbfgs
seed 1724357167
eta 0.1
numSteps -1
numTrials 1
plot False
verbose True
output afqmc.h5
dumpTrials
adding flags
[CpuDevice(id=0)]
default dtype: float64
Reading hopping from spin sector 0
Running in Slater Detemrinant Mode
energyCall: Etotal=(0.9667596040380748+0j) with EK=(-12.35177544441989+0j) EU=(5.854828038995469+0j) EU1=(5.463707008753402+0j) EU2=(2.000000000709093+0j) EJ=0 Eheisenber=0
Reference HF Energy = 0.9667596040380748
energyCall: Etotal=(0.9667596040380748+0j) with EK=(-12.35177544441989+0j) EU=(5.854828038995469+0j) EU1=(5.463707008753402+0j) EU2=(2.000000000709093+0j) EJ=0 Eheisenber=0
See the examples in Running SAFIRE for how to run AFQMC.