Light-weight generic iterative self-consistency loop.
Basic usage
green-sc
is a header-only C++ template library that implements generic iterative self-consistency loop.
To add this library into your project, first
Include(FetchContent)
FetchContent_Declare(
green-sc
GIT_REPOSITORY https://github.com/Green-Phys/green-sc.git
GIT_TAG origin/main # or a later release
)
FetchContent_MakeAvailable(green-sc)
Add predefined alias GREEN::SC
it to your target:
target_link_libraries(<target> PUBLIC GREEN::SC)
And then simply include the following header:
#include <green/sc/sc_loop.h>
It uses green-params
library to read parameters either from a command line or from parameter string.
Please check green-params
documentation for more details.
The following parameters have to be specified:
itermax
- maximum number of iterations to runmixing_type
- type of mixing between iterationsmixing_weight
- how mach of a previous iteration to be mixed with the current iteration resultsresults_file
- file to store results at each iterationrestart
- checkpointingthreshold
- convergence threshold, iterations will be stopped if convergence creteria is smaller thanthreshold
.
Class has to be parametrized with user defined Dyson
type. Dyson
publicly defines the following three types: G
- type for Green’s function, Sigma1
- type for static part of self-energy,
Sigma_tau
- type for dynamic-part of self-energy, and implements the following methods:
solve(G&, Sigma1&, Sigma_tau&)
- for a given self-energiesdiff(G&, Sigma1&, Sigma_tau&)
- computes convergence creteriadump_iteration(int iter, const std::string&f)
- store additional data into a results filef
for a given iterationiter
.
The method solve
needs four parameters:
- Solver - solver object that implements
solve(A, B, C)
Even though we use diagrammatic names such as Green’s function and self-energy, this library can be used to solve arbitrary equation that can be written in iterative form. Here is a small example of solving square equation $\beta X^2 - X + \alpha = 0$
using namespace green::sc;
// define dyson solver
class square_equation_dyson {
public:
using G = double;
using Sigma1 = double;
using Sigma_tau = double;
double _alpha;
double _beta;
double _diff;
square_equation_dyson(const green::params::params &p) : _alpha(p["a"]),
_beta(p["b"]) {}
void solve(G& g, Sigma1& sigma1, Sigma_tau& sigma_tau) {
double g_new = _alpha + _alpha * sigma1 * g;
_diff = std::abs(g - g_new);
g = g_new;
}
double diff(const G& g, const Sigma1& sigma1, const Sigma_tau& sigma_tau) {
return _diff;
}
void dump_iteration(size_t iter, const std::string& result_file){};
};
// define solver class
class square_equation_solver {
public:
double _U;
second_power_equation_solver(double alpha, double beta) : _U(beta / alpha) {}
void solve(const G& g, Sigma1& sigma1, Sigma_tau& sigma_tau) { sigma1 = _U * g; }
};
p.define<double>("a", "a", 1.0);
p.define<double>("b", "b", 0.5);
// create with a given green-params parameter object:
sc_loop<square_equation_dyson> sc(MPI_COMM_WORLD, p);
double g = 0, s1=0, st = 0;
// create solver for square equation
square_equation_solver solver(p["a"], p["b"]);
// solve equation
sc.solve(solver, g, s1, st);