GreenFunc
GreenFunc.jl is a differentiable numerical framework to manipulate multidimensional Green's functions.
Features
MeshArray
type as an array defined on meshes, which provides a generic data structure for Green's functions, vertex functions or any other correlation/response functions. Structured (non)uniform Brillouin Zone meshes powered by the package
BrillouinZoneMeshes.jl
.  Structured (non)uniform temporal meshes for (imaginary)time or (Matsubara)frequency domains powered by the pacakge
CompositeGrids.jl
.  Compat representation based on the Discrete Lehmann representation (DLR) powered by the package
Lehmann.jl
.  Accurate and fast Fourier transform.
 Interface to the
TRIQS
library.
Installation
This package has been registered. So, simply type import Pkg; Pkg.add("GreenFunc")
in the Julia REPL to install.
Basic Usage
Example 1: Green's function of a single level
We first show how to use MeshArray
to present Green's function of a singlelevel quantum system filled with spinless fermionic particles. We assume that the system could exchange particles and energy with the environment so that it's equilibrium state is a grand canonical ensemble. The singleparticle Green's function then has a simple form in Matsubarafrequency representation:
using GreenFunc
β = 100.0; E = 1.0 # inverse temperature and the level energy
ωₙ_mesh = MeshGrids.ImFreq(100.0, FERMION; Euv = 100E) # UV energy cutoff is 100 times larger than the level energy
Gn = MeshArray(ωₙ_mesh; dtype=ComplexF64); # Green's function defined on the ωₙ_mesh
for (n, ωₙ) in enumerate(Gn.mesh[1])
Gn[n] = 1/(ωₙ*im  E)
end

Green's function describes correlations between two or more spacetime events. The spacetime continuum needs to be discretized into spatial and temporal meshes. This example demonstrates how to define a onebody Green's function on a temporal mesh. The package provides three types of temporal meshes: imaginarytime grid, Matsubarafrequency grid, and DLR grid. The latter provides a generic compressed representation for Green's functions (We will show how to use DLR later). Correspondingly, They can be created with the
ImTime
,ImFreq
, andDLRFreq
methods. The user needs to specify the inverse temperature, whether the particle is fermion or boson (using the constantFERMION
orBOSON
). Internally, a set of nonuniform grid points optimized for the given inverse temperature and the cutoff energy will be created with the given parameters. 
Once the meshes are created, one can define a
MeshArray
on them to represent the Green's functionGn
. The constructor ofMeshArray
takes a set of meshes and initializes a multidimensional array. Each mesh corresponds to one dimension of the array. The data type of theMeshArray
is specified by the optional keyword argumentdtype
, which is set toFloat64
by default. You can access the meshes (stored as a tuple) withGn.mesh
and the array data withGn.data
. 
By default,
Gn.data
is left undefined if not specified by the user. To initialize it, one can either use the optional keyword argumentdata
in the constructor or use the iterator interface of the meshes and theMeshArray
.
Example 2: Green's function of a free electron gas
Now let us show how to create a Green's function of a free electron gas. Unlike the spinless fermionic particle, the electron is a spin1/2 particle so that it has two inner states. In free space, it has a kinetic energy CompositeGrids
package to generate momentum grids and how to treat the multiple inner states and the meshes with MeshArray
.
using GreenFunc, CompositeGrids
β = 100.0; E = 1.0 # inverse temperature and the level energy
ωₙ_mesh = MeshGrids.ImFreq(100.0, FERMION; Euv = 100E) # UV energy cutoff is 100 times larger than the level energy
kmesh = SimpleGrid.Uniform{Float64}([0.0, 10.0], 50); # initialze an uniform momentum grid
G_n = MeshArray(1:2, 1:2, kmesh, ωₙ_mesh; dtype=ComplexF64); # Green's function of free electron gas with 2x2 innerstates
for ind in eachindex(G_n)
q = G_n.mesh[3][ind[3]]
ω_n = G_n.mesh[4][ind[4]]
G_n[ind] = 1/(ω_n*im  (q^2E))
end

One can generate various types of grids with the
CompositeGrids
package. TheSimpleGrid
module here provides several basic grids, such as uniform grids and logarithmically dense grids. TheUniform
method here generates a 1D linearly spaced grid. The user has to specify the number of grid pointsN
and the boundary points[min, max]
. One can also combine arbitrary numbers ofSimpleGrid
subgrids with a userspecified pattern defined by apanel grid
. These more advanced grids optimized for different purposes can be found in this link. 
The constructor of
MeshArray
can take any iterable objects as one of its meshes. Therefore for discrete inner states such as spins, one can simply use a1:2
, which is aUnitRange{Int64}
object.
Example 3: Green's function of a Hubbard lattice
Now we show how to generate a multidimensional Green's function on a Brillouin Zone meshe. We calculate the Green's function of a free spinless Fermi gas on a square lattice. It has a tightbinding dispersion
using GreenFunc
using GreenFunc: BrillouinZoneMeshes
DIM, nk = 2, 8
lattice = Matrix([1.0 0; 0 1]')
br = BrillouinZoneMeshes.BZMeshes.Cell(lattice=lattice)
bzmesh = BrillouinZoneMeshes.BZMeshes.UniformBZMesh(cell=br, size=(nk, nk))
ωₙmesh = ImFreq(10.0, FERMION)
g_freq = MeshArray(bzmesh, ωₙmesh; dtype=ComplexF64)
t = 1.0
for ind in eachindex(g_freq)
q = g_freq.mesh[1][ind[1]]
ωₙ = g_freq.mesh[2][ind[2]]
g_freq[ind] = 1/(ωₙ*im  (2*t*sum(cos.(q))))
end
 For lattice systems with multidimensional Brillouin zone, the momentum grids internally generated with the
BrillouinZoneMeshes.jl
package. Here aUniformMesh{DIM,N}(origin, latvec)
generates a linearly spaced momentum mesh on the first Brillouin zone defined by origin and lattice vectors given. For more detail, see the link.
Example 4: Fourier Transform of Green's function with DLR
DLR provides a compact representation for onebody Green's functions. At a temperature GreenFunc.jl
provide DLR through the package Lehmann.jl
.
In the following example, we demonstrate how to perform DLRbased Fourier transform in GreenFunc.jl
between the imaginarytime and the Matsubarafrequency domains back and forth through the DLR representation.
using GreenFunc, CompositeGrids
β = 100.0; E = 1.0 # inverse temperature and the level energy
ωₙ_mesh = ImFreq(100.0, FERMION; Euv = 100E) # UV energy cutoff is 100 times larger than the level energy
kmesh = SimpleGrid.Uniform{Float64}([0.0, 10.0], 50); # initialze an uniform momentum grid
G_n = MeshArray(1:2, 1:2, kmesh, ωₙ_mesh; dtype=ComplexF64); # Green's function of free electron gas with 2x2 innerstates
for ind in eachindex(G_n)
q = G_n.mesh[3][ind[3]]
ω_n = G_n.mesh[4][ind[4]]
G_n[ind] = 1/(im*ω_n  (q^2E))
end
G_dlr = to_dlr(G_n) # convert G_n to DLR space
G_tau = to_imtime(G_dlr) # convert G_dlr to the imaginarytime domain
#alternative, you can use the pipe operator
G_tau = G_n > to_dlr > to_imtime #Fourier transform to (k, tau) domain
The imaginarytime Green's function after the Fourier transform shoud be consistent with the analytic solution

For any Green's function that has at least one imaginarytemporal grid (
ImTime
,ImFreq
, andDLRFreq
) in meshes, we provide a set of operations (to_dlr
,to_imfreq
andto_imtime
) to bridge the DLR space with imaginarytime and Matsubarafrequency space. By default, all these functions find the dimension of the imaginarytemporal mesh within Green's function meshes and perform the transformation with respect to it. Alternatively, one can specify the dimension with the optional keyword argumentdim
. Be careful that the original version of DLR is only guaranteed to work with onebody Green's function. 
Once a spectral density
G_dlr
in DLR space is obtained, one can useto_imfreq
orto_imtime
methods to reconstruct the Green's function in the corresponding space. By default,to_imfreq
andto_imtime
uses an optimized imaginarytime or Matsubarafrequency grid from the DLR. User can assign a target imaginarytime or Matsubarafrequency grid if necessary. 
Combining
to_dlr
,to_imfreq
andto_imtime
allows both interpolation as well as Fourier transform. 
Since the spectral density
G_dlr
can be reused whenever the user wants to change the grid points of Green's function (normally through interpolation that lost more accuracy than DLR transform), we encourage the user always to keep theG_dlr
objects. If the intermediate DLR Green's function is not needed, the user can use piping operator>
as shown to do Fourier transform directly betweenImFreq
andImTime
in one line.
Interface with TRIQS
TRIQS (Toolbox for Research on Interacting Quantum Systems) is a scientific project providing a set of C++ and Python libraries for the study of interacting quantum systems. We provide a direct interface to convert TRIQS objects, such as the temporal meshes, the Brillouin zone meshes, and the multidimensional (blocked) Green's functions, to the equivalent objects in our package. It would help TRIQS users to make use of our package without worrying about the different internal data structures.
The interface is provided by an independent package NEFTInterface.jl
. We provide several examples of interfacing TRIQS and GreenFunc.jl
in the NEFTInterface.jl
README.