Skip to content

Function library

Urs Haehner edited this page Jul 19, 2018 · 3 revisions

The need of a suitable data structure for efficient storage and easy manipulation of objects like Hamiltonians, Green's functions, or self-energies led to the development of DCA++'s function library. Its applicability, however, goes beyond the mentioned physical quantities, as the library allows to work with any function defined on a physical space or an arbitray indexable domain. The main component is the function class, that, like a mathematical function, assigns a value/object of the target space to each element of its domain.
The purpose of this page is to give a basic introduction to the function library and provide the knowledge that is required to post process the output of a DCA++ calculation. For more examples we refer to the function library's unit tests.

Elements of the function library (except for the physics domains) are declared in the namespace dca::func.

Domains

TODO: Explain need/usage of dmn_0.

Domains are classes that represent the discrete or discretized space, on which functions are defined.
Domains are types (not objects), meaning all member functions are static.
To be used within the function library, domain classes are required to satisfy the following basic interface:

// Returns the name of the domain.
static const std::string& get_name();

// Returns the size of the domain.
static std::size_t get_size();

// Returns the elements of the domain.
// At the moment, other components of the function library require this method to return a non-const reference.
static /*const*/ std::vector<ElementType>& get_elements();

In addition, some domains provide a write method to write out the domain's name and its elements.

template <typename Writer>
static void write(Writer& writer);

Example: Imaginary time domain

Physics domains

Physics domains contain various predefined domain classes. On the one hand, they implement real and momentum space grids (e.g. the DCA cluster), and discrete or discretized physical spaces (e.g. Matsubara freqency or imaginary time). On the other hand, they are built for a number of enumerable objects (e.g. electron spin, DCA iteration), which allows to define functions on them. The code provides the following (physics) domains, that are declared in the namespace dca::phys::domains:

Class name Physical space
time_domain Imaginary time domain [-β,β]
TBC ...

dca::func::dmn

Defined in header dmn.hpp:

template <int size, class element_t = int>
class dmn;

The class allows to create custom domains, that can be used with the function class. Size and element type can be chosen via template arguments and a static member function is provided to set the elements.

Example:

using TwoElementDmn = dca::func::dmn<2, int>;
std::vector<int> elements{42, 99};
TwoElementDmn::set_elements(elements);

dca::func::dmn_variadic

Defined in header dmn_variadic.hpp:

template <typename... domain_list>
class dmn_variadic : public domain;

The class builds the cartesian product domain of an arbitrary number of subdomains. It allows to create functions that depend on multiple variables.

Example:
The cluster self-energy in DCA has two band and two spin indices, and is a function of cluster momentum and fermionic Matsubara frequency:

using ClusterSelfEnergyDomain = dca::func::dmn_variadic<BandDmn, SpinDmn, BandDmn, SpinDmn, KClusterDmn, FreqDmn>;

dca::func::function

TODO: Extend.

Defined in header function.hpp:

template <typename scalartype, class domain>
class function;

For each element of its domain the class stores an object of type scalartype.
The operator() allows read and write access.

Examples:

// Simple example
using MyDomain = dca::func::dmn<3, int>;
dca::func::function<double, MyDomain> f;  // Initialized with zeros.
f(0) = 3.14;
f(1) = 2. * f(0);

// Function to store the cluster self-energy
dca::func::function<std::complex<double>, ClusterSelfEnergyDomain> cluster_self_energy;

Clone this wiki locally