API Reference
The package is organised into two core objects that represent the main components of the ghost-GA method, namely the Fragment and the Lattice objects.
The Fragment class represents the locally correlated space (site or cluster) and takes care of solving the correspondig embedding problem and updating the self-energy and hybridization parameters.
The Lattice class represents the lattice, takes care of the Brillouin-zone integration, and makes the fragments talk to each other.
The software provides a collection of impurity solvers, which are organised in the gem.solvers subpackage.
Every solver inherits from gemSolver and implements the common interface documented in gem.solvers.solver_template, which allows them to be used interchangeably within the self-consistency loop.
Fragment checks that the solver it is given is a gemSolver.
Complete calculations, from the construction of these objects to the self-consistency loop, are given in the user guide.
Core Modules
Everything is expressed in spin-orbital indices, with spin as the fastest
index: level 2*a is the down spin of orbital a and level 2*a+1 is its
up spin. An orbital-space matrix is lifted to spin-orbital space with
np.kron(m, np.eye(2)). The same ordering is assumed by the \(S_z\)
sectors of SimpleED and by the spin operators it
builds.
fragment
The gem.fragment module provides the Fragment
class, which represents a single correlated site (or cluster) together with its ghost
orbital bath. It holds the embedding Hamiltonian, the quasiparticle weights, and the
self-energy parameters (\(R\), \(\Lambda\)) and hybridisation parameters
(\(D\), \(\Lambda_c\)) that connect the fragment to the lattice.
It is constructed as:
Fragment(nimp, nbath, eloc, Utensor, solver,
Lambda=None, R=None, Lambda_c=None, D=None, verbose=0)
Argument |
Type / shape |
Meaning |
|---|---|---|
|
int |
Number of impurity spin-orbital levels (orbitals × spins). |
|
int |
Number of ghost bath spin-orbital levels. It must be a multiple of
|
|
ndarray |
Local one-body Hamiltonian of the correlated space without the chemical potential. |
|
ndarray |
Local interaction tensor in the convention
\(\frac{1}{2}\sum U_{ijkl} c^\dagger_i c_j c^\dagger_k c_l\), i.e. a
Hubbard \(U n_\uparrow n_\downarrow\) is entered as
|
|
The impurity solver, already constructed for |
|
|
ndarray |
Starting self-energy parameter \(\Lambda\). Default: a
|
|
ndarray |
Starting self-energy parameter \(R\). Default: uniform. |
|
ndarray |
Starting hybridisation parameter \(\Lambda_c\). Default: a
|
|
ndarray |
Starting hybridisation parameter \(D\). Default: uniform. |
|
int, default |
Verbosity of the printout; maximum for |
All four parameter matrices are shape-validated, so a wrongly sized array raises immediately. Passing the converged matrices of a previous run is the standard way to continue a sweep in \(U\).
The key methods are:
solve_impurity()— solves the quantum-impurity (embedding) problem at a given chemical potential and temperature, returning the ground-state (or thermal) density matrix.update_self_energy()— updates the ghost-GA self-energy parameters \(R\) and \(\Lambda\) by imposing the stationarity condition of the ghost-GA energy functional with respect to these parameters.update_hybridization()— updates the hybridisation parameters \(D\) and \(\Lambda_c\) by imposing the stationarity condition of the ghost-GA energy functional with respect to these parameters.
lattice
The gem.lattice module provides the Lattice
class, which wraps the Brillouin-zone integration over the non-interacting dispersion.
It assembles the quasiparticle Hamiltonian from the self-energy parameters of all
fragments, integrates it over the Brillouin zone to obtain the thermal expectation values
to update the hybridization function, and feeds these results back to the fragments.
It is constructed as:
Lattice(ek_list, wk_list=None, verbose=0, use_mpi=True, comm=None)
Argument |
Type / shape |
Meaning |
|---|---|---|
|
ndarray |
Non-interacting inter-fragment dispersion, one matrix per k-point (or per energy,
for a density-of-states calculation). |
|
ndarray |
Integration weights, which must sum to 1 . Default: uniform weights |
|
int, default |
Verbosity of the printout. |
|
bool, default |
Distribute the k-point sums over the ranks of |
|
mpi4py communicator, optional |
Defaults to |
The k-points are split into contiguous chunks once, at construction, and every k
sum is closed by an allreduce, so all ranks leave with identical results — which
matters for fit_mu_quasiparticle(), whose bisection
must take the same branch everywhere. A warning is issued when there are more
ranks than k-points.
The key methods are:
solve_qp()— performs the quasiparticle Brillouin-zone integration given the current self-energy parameters of each fragment, computes the quasiparticle thermal expectation values and feeds these results back to the fragments.fit_mu()— adjusts the chemical potential iteratively until the total lattice filling matches a prescribed target.
gdmft — Simple Self-Consistency Driver
The gem.gdmft module provides a legacy implementation of the Gdmft
class, which drives the ghost-GA self-consistency loop for a simple single fragment case.
It manages the exchange of hybridisation functions between the lattice and the impurity fragments and evaluates
the total-energy functional.
solvers
The gem.solvers subpackage collects all supported impurity solvers.
Each solver inherits from gemSolver and
implements the common interface documented in
gem.solvers.solver_template.
Solver-specific parameters are never passed by the Fragment:
they are given once, as the solver_params dictionary, when the solver is built
(it is deep-copied, and a non-dict raises TypeError). They can still be changed
afterwards through fragment.solver.solver_params, and unknown keys are ignored.
Available solvers:
SimpleED (
simple_ed) — lightweight exact diagonalisation, no extra dependencies.
simple_ed
The gem.solvers.simple_ed module provides
SimpleED, which diagonalises the embedding
Hamiltonian exactly, sector by sector, and obtains the expectation values as
thermal/degeneracy-weighted averages over the included sectors.
It is constructed as:
SimpleED(norb, use_Ntot=False, use_Sz=False, dtype=np.complex128,
N_sector=None, Sz_sector=None, solver_params=None, comm=None)
Argument |
Type / default |
Meaning |
|---|---|---|
|
int |
Number of spin-orbital levels of the embedding problem, i.e. the
fragment’s |
|
bool, default |
Exploit particle-number conservation. |
|
bool, default |
Exploit \(S_z\) conservation. |
|
int or |
Particle-number sector to solve. |
|
int/half-integer or |
\(S_z\) sector to solve. |
|
default |
Working precision. |
|
dict, optional |
Solver-specific options; see the table below. |
|
mpi4py communicator, optional |
Communicator over whose ranks the sectors are distributed (default
|
The symmetry flags only decide whether the Hamiltonian is block-diagonalised;
which blocks are kept is decided by N_sector and Sz_sector. At half
filling with no symmetry breaking the usual — and by far the cheapest — choice is
use_Ntot=True, use_Sz=True, N_sector=ntot//2, Sz_sector=0; drop
N_sector/Sz_sector when the ground state may leave that sector, and drop
use_Sz when the calculation is magnetic or has off-diagonal spin terms.
Under MPI each rank builds and diagonalises only the sectors it owns, while the
reduced quantities are identical on every rank. build_Hemb, solve_Hemb,
calc_density_matrix, compute_E1loc, compute_E2loc and
calc_double_occ are therefore collective — calling one of them inside an
if rank == 0: block deadlocks.
Real and complex precision
dtype is a request, not a guarantee. A real type is honoured only when
nothing in the embedding problem carries an imaginary part, which is checked at
every build_Hemb:
the one-body Hamiltonian, assembled from
eloc,DandLambda_c,the interaction tensor
Utensor,the
sy_penpenalty, whose \(\hat{S}_y\) operator is complex by construction.
If one of these is not real, the fallback is using complex128 and
a warning is issued once — the results stay correct, only the speedup is lost.
solver.data_type always holds the precision actually in use.
The keys SimpleED reads from solver_params
are:
Key |
Default |
Meaning |
|---|---|---|
|
|
Number of eigenvalues to compute per sector. |
|
|
Sectors with a dimension below this are diagonalised fully with
|
|
|
|
|
|
|
|
|
Smallest Boltzmann weight kept in the partition function at \(T > 0\). |
|
|
Coefficient of a \(\hat{S}^2\) penalty added to the embedding Hamiltonian, to enforce a spin singlet. |
|
|
Coefficients of \(\hat{S}_x^2\), \(\hat{S}_y^2\), \(\hat{S}_z^2\) penalties, to disfavour magnetisation along that axis. |
|
|
Never store the Hamiltonian, the \(c^\dagger_i c_j\) operators or the spin operators; apply them on the fly instead. Memory per sector drops from \(O(\dim \cdot \texttt{norb}^2)\) to \(O(\dim)\), at a few times the cost per matvec. |
|
|
In matrix-free mode, build a direct Fock-state lookup table of
\(2^{\texttt{norb}}\) entries when |
|
|
Set to |
|
|
Exponent in the sector cost model |
Two caveats on the spin penalties. They are only meaningful at \(T = 0\) —
they change the spectrum, so at \(T > 0\) the Boltzmann weights come out
wrong, and a warning is issued. And they are unavailable in matrix-free mode,
which does not build \(\hat{S}^2\), \(\hat{S}_x\), \(\hat{S}_y\),
\(\hat{S}_z\) at all; combining the two raises NotImplementedError.
They can also be passed directly to build_Hemb, in which case the explicit
argument wins over the solver_params entry.
Utilities
Helper routines used throughout the code:
gem.utilities— general linear-algebra and Green’s-function helpers.gem.delta_fit— routines to perform thermal density matrix fitting of the hybridisation function and self-energy parameters. to a discrete bath.gem.mpi— common helper routines for MPI parallelization.