TRIQS/TRIQS 4.0.0
Researching Interacting Quantum Systems
Loading...
Searching...
No Matches
Green's functions

The gf class is the central container of TRIQS. A Green's function gf<Mesh, Target> couples a mesh (the domain — real or imaginary time, real or imaginary frequency, Legendre, DLR, Brillouin zone, ...) with a target (the value at each mesh point — a scalar, a matrix, or a higher-rank tensor). The same container therefore represents \(G(\tau)\), \(G(i\omega_n)\), \(G(t)\), \(G(\omega)\), ... with a uniform interface.

The examples below show how to construct these objects, fill them, and evaluate them. Each section is a self-contained main() whose source lives in doc/doxygen/examples/ and is compiled by doc/doxygen/examples/CMakeLists.txt, so the snippets cannot drift out of sync with the library.

For the equivalent Python usage, see the Python user guide and the triqs.gfs API documentation.

Matsubara Green's functions

A single-variable Matsubara Green's function lives on a mesh::imfreq (fermionic or bosonic). Here we construct \(G(i\omega) = \frac{1}{i\omega - 3}\) by filling it from a placeholder expression and then read back a value. The mesh, target shape and statistic are fixed at construction.

#include <triqs/gfs.hpp>
#include <triqs/mesh.hpp>
using namespace triqs;
using namespace triqs::gfs;
using nda::clef::placeholder;
int main() {
// Create a Matsubara-frequency mesh
double beta = 1; // inverse temperature
int n_iw = 100; // number of Matsubara frequencies
auto iw_mesh = mesh::imfreq{beta, Fermion, n_iw};
// Create and fill a 1x1 Matsubara Green function
auto g = gf{iw_mesh, {1, 1}};
placeholder<0> iw_;
g[iw_] << 1 / (iw_ - 3);
std::cout << g(0) << std::endl;
// An equivalent way to initialize
g() = 0.0;
for (auto w : g.mesh()) g[w] = 1 / (w - 3);
std::cout << g(0) << std::endl;
//an incorrect way : throws exception as expected
//g(w) returns a const_view: () are to be used for interpolation, see bottom of the page
//for (auto w : g.mesh()) g(w) = 1/(w-3);
}
The owning Green's function container.
Definition gf.hpp:194
Imaginary frequency mesh type.
Definition imfreq.hpp:102
Umbrella header for the Green's function library.
Umbrella header for the TRIQS mesh types.
constexpr nda::clef::placeholder< 3 > w
Placeholder for the frequency .

Output:

[[(-0.158986,-0.16649)]]
[[(-0.158986,-0.16649)]]

Green's functions can also depend on several arguments. The next example builds a two-frequency object \(G(i\omega, i\nu) = \frac{1}{i\omega + i\nu - 4}\) on a product of two Matsubara meshes, illustrating how gf generalizes to multi-variable domains.

#include <triqs/gfs.hpp>
#include <triqs/mesh.hpp>
using namespace triqs;
using namespace triqs::gfs;
using nda::clef::placeholder;
int main() {
// Create a Matsubara-frequency mesh
double beta = 1; // inverse temperature
int n_iw = 100; // number of Matsubara frequencies
auto iw_mesh = mesh::imfreq{beta, Fermion, n_iw};
// Create and fill a 1x1 Matsubara Green function on the product mesh
auto g2 = gf{iw_mesh * iw_mesh, {1, 1}};
//the shortest way to fill a gf
placeholder<0> iw_;
placeholder<1> inu_;
g2[iw_, inu_] << 1 / (iw_ + inu_ - 4);
std::cout << g2(0, 0) << std::endl;
// An equivalent way to initialize
g2() = 0.0;
for (auto [w, nu] : g2.mesh()) g2[w, nu] = 1 / (w + nu - 4);
std::cout << g2(0, 0) << std::endl;
}

Output:

[[(-0.0721001,-0.113255)]]
[[(-0.0721001,-0.113255)]]

Imaginary-time Green's functions

The imaginary-time counterpart \(G(\tau)\) lives on a mesh::imtime. The construction mirrors the Matsubara case — only the mesh type changes — which is the whole point of the generic gf container.

#include <triqs/gfs.hpp>
#include <triqs/mesh.hpp>
using namespace triqs;
using namespace triqs::gfs;
int main() {
// Create a imaginary-time mesh
double beta = 1;
int n_times = 101; // number of time-points
auto tau_mesh = mesh::imtime{beta, Fermion, n_times};
// Create a scalar-valued Green function g[tau] on the tau_mesh
auto g = gf<imtime, scalar_valued>{tau_mesh};
}
Imaginary time mesh type.
Definition imtime.hpp:68

Real-time Green's functions

A real-time Green's function \(G(t)\) is defined on a mesh::retime spanning [t_min, t_max]. The target determines the value stored at each time. For a scalar-valued \(G(t)\):

#include <triqs/gfs.hpp>
#include <triqs/mesh.hpp>
using namespace triqs;
using namespace triqs::gfs;
int main() {
// Create a real-time mesh
double tmin = 0, tmax = 10; // the time interval
int n_times = 101; // number of time-points
auto t_mesh = mesh::retime{tmin, tmax, n_times};
// Create a scalar-valued Green function on the t_mesh
auto g = gf<retime, scalar_valued>{t_mesh};
}
Real time mesh type.
Definition retime.hpp:70

For a matrix-valued target of size n x m (e.g. a multi-orbital propagator):

#include <triqs/gfs.hpp>
#include <triqs/mesh.hpp>
using namespace triqs;
using namespace triqs::gfs;
int main() {
// Create a real-time mesh on interval [tmin, tmax]
double tmin = 0, tmax = 10;
int n_times = 101; // number of time-points
auto t_mesh = mesh::retime{tmin, tmax, n_times};
// Create a scalar-valued Green function on the t_mesh
auto g = gf<retime, scalar_valued>{t_mesh};
// Create a nxm matrix-valued Green function on the t_mesh
const int n = 2, m = 2;
auto gm = gf<retime, matrix_valued>{t_mesh, {n, m}};
}
many_body_operator_generic< T > n(IndexTypes... indices)
Create a number operator .

The target can have any rank — here a three-index tensor:

#include <triqs/gfs.hpp>
#include <triqs/mesh.hpp>
using namespace triqs;
using namespace triqs::gfs;
int main() {
// Number of time-points to be used
int n_times = 101;
// Create a real-time mesh on interval [tmin, tmax]
double tmin = 0, tmax = 10;
auto t_mesh = mesh::retime{tmin, tmax, n_times};
// Create a imaginary-time mesh
double beta = 1;
auto tau_mesh = mesh::imtime{beta, Fermion, n_times};
// Create Green function g[t,tau] on product-mesh with values of shape (2,2,2)
auto g = gf<prod<retime, imtime>, tensor_valued<3>>{t_mesh * tau_mesh, {2, 2, 2}};
}
Target type for a complex tensor-valued Green's function.
Definition targets.hpp:83

Two-time Green's functions

Just like the two-frequency example above, a real-time object can depend on two times \(G(t, t')\) by using a product mesh:

#include <triqs/gfs.hpp>
#include <triqs/mesh.hpp>
using namespace triqs;
using namespace triqs::gfs;
int main() {
// Create a real-time mesh on the interval [tmin, tmax]
double tmin = 0, tmax = 10;
int n_times = 101; // number of time-points
auto t_mesh = mesh::retime{tmin, tmax, n_times};
// Create a scalar-valued Green function g[t1,t2] on the product-mesh and initialize
auto g = gf<prod<retime, retime>, scalar_valued>{t_mesh * t_mesh};
}
Target type for a complex scalar-valued Green's function.
Definition targets.hpp:188

Filling a GF with placeholders

TRIQS Green's functions integrate with the CLEF placeholder mini-language: assigning a lazy expression in a placeholder fills every mesh point without writing an explicit loop. This is the idiomatic way to initialize a gf from a closed-form expression.

#include <triqs/gfs.hpp>
#include <triqs/mesh.hpp>
using namespace triqs;
using namespace triqs::gfs;
int main() {
// Create a real-time mesh on the interval [tmin, tmax]
double tmin = 0, tmax = 10;
int n_times = 101; // number of time-points
auto t_mesh = mesh::retime{tmin, tmax, n_times};
// Create a scalar-valued Green function g[t1,t2] on the product-mesh and initialize
auto g = gf<prod<retime, retime>, scalar_valued>{t_mesh * t_mesh};
nda::clef::placeholder<0> t1_;
nda::clef::placeholder<1> t2_;
g[t1_, t2_] << 2 * t1_;
}

Interpolating the GF at an arbitrary point

Calling a Green's function with parentheses evaluates it at an arbitrary point of its domain using the interpolation rule the mesh declares (linear in imaginary time, exact in Matsubara, etc.) — as opposed to bracket access [], which looks up an existing mesh point.

#include <triqs/gfs.hpp>
#include <triqs/mesh.hpp>
using namespace triqs;
using namespace triqs::gfs;
int main() {
// Create a real-time mesh on the interval [tmin, tmax]
double tmin = 0, tmax = 10;
int n_times = 101; // number of time-points
auto t_mesh = mesh::retime{tmin, tmax, n_times};
// Create a scalar-valued Green function g[t1,t2] on the product-mesh and initialize
auto g = gf<prod<retime, retime>, scalar_valued>{t_mesh * t_mesh};
nda::clef::placeholder<0> t1_;
nda::clef::placeholder<1> t2_;
g[t1_, t2_] << 2 * t1_;
// Interpolate to obtain value in the domain
std::cout << g(0.24, 0.36) << std::endl;
}

Output:

(0.48,0)