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.