-
Notifications
You must be signed in to change notification settings - Fork 29
Function library
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.
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 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 | ... |
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);
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>;
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;